Frage

Trying to experiment a bit with C++ CLI, targetting .NET 4.0 (not 4.5), I'm getting a slightly annoying issue. The code below gives an IntelliSense warning in my Visual Studio 2012; it complains that BindingFlags is available in multiple assemblies. (The code compiles fine, but the warning is annoying since it makes the IntelliSense malfunction.)

#include "stdafx.h"
#include <vcclr.h>

using namespace System;
using namespace System::Reflection;

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Hello World");
    Console::ReadKey();

    auto properties = Console::typeid->GetProperties(BindingFlags::Instance | BindingFlags::Public);

    return 0;
}

If I remove the vcclr.h file, everything works fine. I looked at the file, and it seems to have a line like this:

#using <mscorlib.dll>

I presume this is why I'm getting an error. mscorlib.dll is already referenced automatically by my project, and that using makes Visual Studio try to load it one more time from another location => conflict.

Using the 'Go to definition' (F12) function on BindingFlags gives me these paths:

enum class System::Reflection::BindingFlags - c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll
enum class System::Reflection::BindingFlags - c:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll

How do I work around this? I definitely do not want to target .NET 4.5 at this point, since all the users in this case are not on .NET 4.5 yet. Nonetheless, it would be "quite nice" to get the IntelliSens working in this case also...

War es hilfreich?

Lösung

Just like Hans very correctly pointed out (thank you!), the current way (without Microsoft fixing the core issue) is to make your own local copy of the vcclr.h. Here is my end result. This works perfectly now with the IntelliSense, which is nice because the new C++ keyword "auto" (= var in C#) is basically useless without working IntelliSense...

(Looking through my version now before submitting, you could obviously also change the define _INC_VCCLR to not collide with Microsoft's version. Then again, I feel this should be more or less of a drop-in replacement for the stock vcclr.h anyway, so it's not a problem for me. Also, you wouldn't want the stuff to be defined twice, if some file accidentally includes vcclr.h instead, so... maybe it's best to keep it like this.)

//
//  vcclr_local.h - modified version of vcclr.h from c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\vcclr.h.
//  Modifications indicated below.
//
//  Copyright (C) Microsoft Corporation
//  All rights reserved.
//

#if _MSC_VER > 1000
#pragma once
#endif

#if !defined(_INC_VCCLR)
#define _INC_VCCLR
#ifndef RC_INVOKED

// Deliberately disabled, since this causes mscorlib.dll to be references twice from two different locations, breaking
// IntelliSense whenever this header file is included.
//#using <mscorlib.dll>
#include <gcroot.h>

#pragma warning(push)
#pragma warning(disable:4400)

#ifdef __cplusplus_cli
typedef cli::interior_ptr<const System::Char> __const_Char_ptr;
typedef cli::interior_ptr<const System::Byte> __const_Byte_ptr;
typedef cli::interior_ptr<System::Byte> _Byte_ptr;
typedef const System::String^ __const_String_handle;
#define _NULLPTR nullptr
#else
typedef const System::Char* __const_Char_ptr;
typedef const System::Byte* __const_Byte_ptr;
typedef System::Byte* _Byte_ptr;
typedef const System::String* __const_String_handle;
#define _NULLPTR 0
#endif


//
// get an interior gc pointer to the first character contained in a System::String object
//
inline __const_Char_ptr PtrToStringChars(__const_String_handle s) {

    _Byte_ptr bp = const_cast<_Byte_ptr>(reinterpret_cast<__const_Byte_ptr>(s));
    if( bp != _NULLPTR ) {
    unsigned offset = System::Runtime::CompilerServices::RuntimeHelpers::OffsetToStringData;
        bp += offset;
    }
    return reinterpret_cast<__const_Char_ptr>(bp);
}

#pragma warning(pop)

#undef _NULLPTR

#endif /* RC_INVOKED */
#endif //_INC_VCCLR
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top