错误:只要使用vcclr.h,“BindingFlags”就不明确了

时间:2013-05-08 21:58:34

标签: .net visual-studio-2012 c++-cli mscorlib

尝试使用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工作也是“相当不错”......

1 个答案:

答案 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