C ++ / CLI-> C#错误C2526:C连接函数无法返回C ++类

我有一个使用VS2010 C#构建的简单.NET dll,它暴露了一个类的2个静态成员

public class Polygon { public static void Test(int test) {} public static void Test(List test) {} } 

然后我从VS2010 C ++创建了一个Console应用程序,并在_tmain上面添加了这个函数

 extern "C" void TestMe() { Polygon::Test(3); } 

添加引用和编译会给我这个错误

 1>WierdError.cpp(9): error C2526: 'System::Collections::Generic::List::GetEnumerator' : C linkage function cannot return C++ class 'System::Collections::Generic::List::Enumerator' 1> with 1> [ 1> T=int 1> ] 1> WierdError.cpp(9) : see declaration of 'System::Collections::Generic::List::Enumerator' 1> with 1> [ 1> T=int 1> ] 1> WierdError.cpp(9) : see reference to class generic instantiation 'System::Collections::Generic::List' being compiled 1> with 1> [ 1> T=int 1> ] 

我的一些观察:

  • 如果删除extern“C”,它会成功编译
  • 如果我将Test(List test)重命名为Test2(List test)它会成功编译

我的问题是,出现了什么问题以及如何从C ++方面解决它。

我目前的解决方法是在C#中重命名该方法,但我宁愿不必这样做,我觉得我的C ++项目中可能缺少一个设置。

编辑:

我在C ++中找到了一个更好的解决方法,看起来我可以将.NET调用包装在另一个函数中。

 void wrapper() { Polygon::Test(3); } extern "C" void TestMe() { wrapper(); } 

这样做似乎很愚蠢,我想知道它是否是一个编译器错误? 令我害怕的是使用这样的方法并且不得不担心C#开发人员可能稍后添加这样的静态方法并打破C ++构建。

我只想在这里拍摄狂野的镜头,原因如下:

在编译期间,MSVC的C ++编译器看到extern "C" function TestMe() Test()在类Polygon调用函数Test()Polygon是编译器的不完整类型。 我想编译器无法看到函数Polygon::Test(3)是返回一个不完整的类型还是返回任何东西,它决定它需要在那个时候返回一个错误,以防该类型变成一个普通的C风格的POD类型。

对于MSVC的一部分,上述似乎是合理的假设,因为(7.5 / 9“链接规范”)C ++标准说:

“从C ++到其他语言定义的对象以及用其他语言在C ++中定义的对象的链接是实现定义和语言相关的。只有在两种语言实现的对象布局策略足够相似的情况下才能实现这种联系。”

这可以解释一旦删除extern C链接规范或将调用替换为Cstyle函数后错误消失。