0

尝试使用 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 尝试从另一个位置再次加载它 => 冲突。

使用 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 在这种情况下也能正常工作会是“非常好的”......

4

1 回答 1

0

就像 Hans 非常正确地指出的那样(谢谢!),当前的方法(没有 Microsoft 修复核心问题)是制作您自己的 vcclr.h 的本地副本。这是我的最终结果。这现在可以与 IntelliSense 完美配合,这很好,因为新的 C++ 关键字“auto”(= C# 中的 var)在没有工作 IntelliSense 的情况下基本上是无用的......

(现在在提交之前查看我的版本,您显然也可以更改定义 _INC_VCCLR 以不与 Microsoft 的版本冲突。再说一次,我觉得这或多或少应该是股票 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
于 2013-05-09T09:31:08.493 回答