C++/CLI: #pragma managed / unmanaged scope

喜欢而已 提交于 2019-12-12 12:17:26

问题


I have a mixed-mode DLL, and a .cpp file in it with both managed and unmanaged code. A simplified repro example looks like this:

#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

This code compiles successfully, however if I uncomment the last line (#pragma unmanaged), it produces following errors:

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>          ]

I've found that I can get rid of the error by adding #pragma managed at the end of my .cpp file. But I still do not understand why the errors occur. This behavior of #pragma unmanaged seems absolutely counter-intuitive to me. Can someone please explain?

As far as I understand:

  • #pragma (un)managed affects code compilation below it. Therefore, if it is defined at the end of .cpp file (nothing below), it should not have any effect.
  • Also http://msdn.microsoft.com/en-us/library/0adb9zxe.aspx says:

    When a template function is instantiated, the pragma state at the time of definition for the template determines if it is managed or unmanaged.

marshal_context template is defined in the included file marshal.h, and should be compiled as managed (because it has explicit #pragma on the previous line) regardless of the #pragma at the bottom of the file.

Am I wrong somewhere?

来源:https://stackoverflow.com/questions/27903454/c-cli-pragma-managed-unmanaged-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!