Pes*_*nat 9 c# c++-cli visual-studio-2010 extern linkage
我有一个使用VS2010 C#构建的简单.NET dll,它暴露了一个类的2个静态成员
public class Polygon
{
public static void Test(int test) {}
public static void Test(List<int> test) {}
}
Run Code Online (Sandbox Code Playgroud)
然后我从VS2010 C++创建了一个Console应用程序,并在_tmain上面添加了这个函数
extern "C" void TestMe()
{
Polygon::Test(3);
}
Run Code Online (Sandbox Code Playgroud)
添加引用和编译会给我这个错误
1>WierdError.cpp(9): error C2526: 'System::Collections::Generic::List<T>::GetEnumerator' : C linkage function cannot return C++ class 'System::Collections::Generic::List<T>::Enumerator'
1> with
1> [
1> T=int
1> ]
1> WierdError.cpp(9) : see declaration of 'System::Collections::Generic::List<T>::Enumerator'
1> with
1> [
1> T=int
1> ]
1> WierdError.cpp(9) : see reference to class generic instantiation 'System::Collections::Generic::List<T>' being compiled
1> with
1> [
1> T=int
1> ]
Run Code Online (Sandbox Code Playgroud)
我的一些观察:
Test(List<int> test),它会成功编译Test2(List<int> test)我的问题是,出现了什么问题以及如何从C++方面解决它.
我目前的解决方法是在C#中重命名该方法,但我宁愿不必这样做,我觉得我的C++项目中可能缺少一个设置.
编辑:
我在C++中找到了一个更好的解决方法,看起来我可以将.NET调用包装在另一个函数中.
void wrapper()
{
Polygon::Test(3);
}
extern "C" void TestMe()
{
wrapper();
}
Run Code Online (Sandbox Code Playgroud)
这样做似乎很愚蠢,我想知道它是否是一个编译器错误?令我害怕的是使用这样的方法,并且不得不担心C#开发人员可能稍后添加这样的静态方法并打破C++构建.
我只是想在这里大胆尝试,理由如下:
在编译期间 MSVC 的 C++ 编译器看到extern "C" function TestMe()正在调用Test()类中的函数Polygon。Polygon是编译器的不完整类型。我猜编译器看不到函数Polygon::Test(3)返回的是不完整的类型还是返回任何东西,它决定在那个时候需要返回一个错误,以防该类型不是普通的 C 风格的 POD 类型。
以上似乎是 MSVC 部分的合理假设,如 C++ 标准 (7.5/9“链接规范”) 所述:
“从 C++ 到其他语言定义的对象以及从其他语言到 C++ 定义的对象的链接是实现定义和语言相关的。只有当两种语言实现的对象布局策略足够相似时,才能实现这种链接。”
这将解释一旦删除extern C链接规范或替换对 Cstyle 函数的调用,错误就会消失。
| 归档时间: |
|
| 查看次数: |
3836 次 |
| 最近记录: |