尝试使用C ++ CLI进行一些实验,针对.NET 4.0(而不是4.5),我遇到了一个有点恼人的问题。下面的代码在我的Visual Studio 2012中给出了一个IntelliSense警告;它抱怨BindingFlags在多个程序集中可用。 (代码编译得很好,但警告很烦人,因为它会导致IntelliSense出现故障。)
#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;
}
如果删除vcclr.h文件,一切正常。我查看了该文件,它似乎有这样的一行:
#using <mscorlib.dll>
我认为这就是我收到错误的原因。我的项目已经自动引用了mscorlib.dll,并且使用它会使Visual Studio再次尝试从另一个位置加载它=&gt;冲突。
使用BindingFlags上的“转到定义”(F12)功能为我提供了以下路径:
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
我该如何解决这个问题?我当然不希望以.NET 4.5为目标,因为在这种情况下所有用户还没有使用.NET 4.5。尽管如此,在这种情况下让IntelliSens工作也是“相当不错”......
答案 0 :(得分:0)
就像Hans非常正确指出的那样(谢谢!),目前的方式(没有Microsoft修复核心问题)是制作自己的vcclr.h本地副本。这是我的最终结果。现在使用IntelliSense可以很好地工作,这很好,因为新的C ++关键字“auto”(= C#中的var)在没有工作IntelliSense的情况下基本没用......
(在提交之前查看我的版本,你显然也可以将define _INC_VCCLR更改为不与微软的版本冲突。然后,我觉得这应该或多或少是对vcclr.h股票的直接替代品。无论如何,所以这对我来说不是问题。而且,你不希望这些东西被定义两次,如果某个文件意外地包含vcclr.h,那么......也许最好保持这样。)
//
// 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