2013-05-08 2 views
0

Попытка немного поэкспериментировать с C++ CLI, нацеливая .NET 4.0 (не 4.5), я получаю немного раздражающую проблему. Код ниже дает предупреждение IntelliSense в моей Visual Studio 2012; он жалуется, что BindingFlags доступен в нескольких сборках. (Код компилируется нормально, но предупреждение раздражает, так как это делает неисправность IntelliSense.)Ошибка: «BindingFlags» неоднозначно всякий раз, когда используется vcclr.h

#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 попыткой загрузить его еще раз из другого места => конфликт.

Использование «Перейти к определению» функции (F12) на BindingFlags дает мне эти пути:

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

Там довольно серьезная проблема, связанная с директивой #using, он жестко закодирован для просмотра в .NE Прежде всего. Это было неуместно, так как .NET 4. Это, без сомнения, * очень * сложно исправить таким образом, чтобы не разбивать много старых проектов. Лучшее место для этого можно найти на сайте connect.microsoft.com. Ограничьте это, сохранив этот код в отдельном файле .cpp. –

+0

Спасибо за подсказку Ханс, я тоже подумал об этом - чтобы локальная копия файла vcclr.h с удаленной линией удалялась ... На основе этого будет сделан ответ. –

ответ

0

Как и Ганс, очень правильно указал (спасибо!), Текущий способ (без Microsoft, фиксирующего основную проблему) чтобы создать собственную локальную копию файла vcclr.h. Вот мой конечный результат. Это прекрасно работает теперь с IntelliSense, что хорошо, потому что новое ключевое слово C++ «auto» (= var в C#) в принципе бесполезно без работы 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 
Смежные вопросы