C++/CLI: #pragma управляемая / неуправляемая область

У меня есть DLL в смешанном режиме и файл.cpp с управляемым и неуправляемым кодом. Упрощенный пример воспроизведения выглядит так:

#include "stdafx.h"
#pragma managed // Just for explicitness (doesn't influence results)
#include <msclr\marshal.h>

void Test()
{
    System::String^ sName = "";
    msclr::interop::marshal_context context;
    context.marshal_as<const TCHAR*>(sName);
}

//#pragma unmanaged // uncomment this line to get errors

Этот код успешно компилируется, однако, если я раскомментирую последнюю строку (#pragma unmanaged), выдает следующие ошибки:

2>  Test.cpp
2>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\msclr\marshal.h(48): error C3280: 'msclr::interop::marshal_context::internal_marshaler<_To_Type,_From_Type,_Needs_Context>::internal_marshaler' : a member-function of a managed type cannot be compiled as an unmanaged function
2>          with
2>          [
2>              _To_Type=const wchar_t *,
2>              _From_Type=System::String ^,
2>              _Needs_Context=true
2>          ]
2>          This diagnostic occurred in the compiler generated function 'msclr::interop::marshal_context::internal_marshaler<_To_Type,_From_Type,_Needs_Context>::internal_marshaler(void)'
2>          with
2>          [
2>              _To_Type=const wchar_t *,
2>              _From_Type=System::String ^,
2>              _Needs_Context=true
2>          ]
2>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\msclr\marshal.h(48): error C3642: 'System::Object::Object(void)' : cannot call a function with __clrcall calling convention from native code
2>          This diagnostic occurred in the compiler generated function 'msclr::interop::marshal_context::internal_marshaler<_To_Type,_From_Type,_Needs_Context>::internal_marshaler(void)'
2>          with
2>          [
2>              _To_Type=const wchar_t *,
2>              _From_Type=System::String ^,
2>              _Needs_Context=true
2>          ]
2>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\msclr\marshal.h(48): error C3175: 'System::Object::Object' : cannot call a method of a managed type from unmanaged function 'msclr::interop::marshal_context::internal_marshaler<_To_Type,_From_Type,_Needs_Context>::internal_marshaler'
2>          with
2>          [
2>              _To_Type=const wchar_t *,
2>              _From_Type=System::String ^,
2>              _Needs_Context=true
2>          ]
2>          This diagnostic occurred in the compiler generated function 'msclr::interop::marshal_context::internal_marshaler<_To_Type,_From_Type,_Needs_Context>::internal_marshaler(void)'
2>          with
2>          [
2>              _To_Type=const wchar_t *,
2>              _From_Type=System::String ^,
2>              _Needs_Context=true
2>          ]
2>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\msclr\marshal.h(48): error C3821: 'msclr::interop::marshal_context::internal_marshaler<_To_Type,_From_Type,_Needs_Context>::internal_marshaler(void)': managed type or function cannot be used in an unmanaged function
2>          with
2>          [
2>              _To_Type=const wchar_t *,
2>              _From_Type=System::String ^,
2>              _Needs_Context=true
2>          ]
2>          This diagnostic occurred in the compiler generated function 'msclr::interop::marshal_context::internal_marshaler<_To_Type,_From_Type,_Needs_Context>::internal_marshaler(void)'
2>          with
2>          [
2>              _To_Type=const wchar_t *,
2>              _From_Type=System::String ^,
2>              _Needs_Context=true
2>          ]
2>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\msclr\marshal.h(282): error C3645: 'msclr::interop::marshal_context::internal_marshaler<_To_Type,_From_Type,_Needs_Context>::internal_marshaler' : __clrcall cannot be used on functions compiled to native code
2>          with
2>          [
2>              _To_Type=const wchar_t *,
2>              _From_Type=System::String ^,
2>              _Needs_Context=true
2>          ]
2>          This diagnostic occurred in the compiler generated function 'msclr::interop::marshal_context::internal_marshaler<_To_Type,_From_Type,_Needs_Context>::internal_marshaler(void)'
2>          with
2>          [
2>              _To_Type=const wchar_t *,
2>              _From_Type=System::String ^,
2>              _Needs_Context=true
2>          ]

Я обнаружил, что могу избавиться от ошибки, добавив #pragma managed в конце моего.cpp файла. Но я до сих пор не понимаю, почему происходят ошибки. Это поведение #pragma unmanaged кажется абсолютно нелогичным для меня. Может кто-нибудь объяснить, пожалуйста?

Насколько я понимаю:

  • #pragma (un)managed влияет на компиляцию кода ниже. Поэтому, если он определен в конце файла.cpp (ничего не указано ниже), это не должно иметь никакого эффекта.
  • Также http://msdn.microsoft.com/en-us/library/0adb9zxe.aspx говорит:

    Когда создается экземпляр функции шаблона, состояние прагмы во время определения шаблона определяет, является ли он управляемым или неуправляемым.

marshal_context шаблон определяется во включенном файле marshal.h и должен быть скомпилирован как управляемый (потому что он имеет явную #pragma в предыдущей строке) независимо от #pragma в нижней части файла.

Я где то не прав?

0 ответов

Другие вопросы по тегам