【问题标题】:C++/CLI->C# error C2526: C linkage function cannot return C++ classC++/CLI->C# 错误 C2526:C 链接函数无法返回 C++ 类
【发布时间】:2011-06-16 17:12:32
【问题描述】:

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

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

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

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

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

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

我的一些观察:

  • 如果我删除 extern "C" 编译成功
  • 如果我将Test(List&lt;int&gt; test) 重命名为Test2(List&lt;int&gt; test),则编译成功

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

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

编辑:

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

void wrapper()
{
    Polygon::Test(3);
}

extern "C" void TestMe()
{
    wrapper();
}

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

【问题讨论】:

  • 我无法重现此错误。您使用什么项目模板来创建 C++/CLI 项目?我怀疑你选错了,因为没有一个 CLR 项目模板定义 _tmain 入口点。
  • 我认为是Win32控制台,然后我进入设置并添加了/clr支持,我明天验证。
  • youtube.com/watch?v=QUuQ-BdHflk - 快进到 2:08 是我所做的。
  • 好吧,FWIW,它在使用 CLR 控制台应用程序模板时对我有用。试一试。
  • 一个 CLR 控制台项目也给了我同样的编译错误

标签: c# visual-studio-2010 c++-cli extern linkage


【解决方案1】:

我只是在这里尝试一下,理由如下:

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

以上似乎是对部分 MSVC 的合理假设,如 C++ 标准(7.5/9“链接规范”)所述:

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

这将解释一旦您删除 extern C 链接规范或替换对 Cstyle 函数的调用,错误就会消失。

【讨论】:

  • 是的,当我在没有外部“C”的情况下将 Polygon::Test 包装在它自己的函数中时消失了。我已经习惯了头文件,我不清楚现在在添加 .NET 程序集引用的世界中它是如何工作的
  • Polygon 不是不完整的类型;在 C++/CLI 中,当添加程序集引用时,该程序集中的所有类型都是完整的。
猜你喜欢
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
相关资源
最近更新 更多