extern C返回类对象

时间:2013-01-27 15:35:12

标签: c++ c extern-c

我希望有一个插件,在其他C ++代码中可以解析更简单的名称。

class B {
};

extern "C" B foo(); // to avoid name mangling in order to be loaded by dlsym

在程序的其他部分(也是在C ++中,与插件共享B类的相同定义):

B (*func)();
func = dlsym("/path/to/so", "foo");
B m = func();

这样的代码是否会导致任何问题,即是否允许(按标准)在extern "C"函数中使用C ++类作为参数或返回类型?它似乎适用于我的gcc,但其他人呢?

3 个答案:

答案 0 :(得分:2)

这应该有用,有几个条件:

  • 如果您打算将B类的定义切换为其他内容,则无效。你唯一可以改变的是foo()的定义。
  • 插件和加载程序必须在二进制级别上同意B类接口。切换编译器(包括版本和一些标志)可以更改此接口。
  • 你显然必须在C ++中强制转换dlsym()的返回值。
  • 无法使用C语言中的类。

答案 1 :(得分:1)

将foo()声明为extern "C"当然允许您使用实际的,未编译的函数名称通过dlsym()加载它,但在加载后不会影响您如何使用该函数。

通常的规则仍然适用。如果你破坏了foo()或类B的二进制兼容性,你将需要重新编译插件,就像你必须重新编译它一样,如果它是一个非常规的非运行时动态库。

答案 2 :(得分:0)

只要您坚持使用C ++并且只使用C ++,它就会起作用。由于显而易见的原因,您将无法在C翻译单元中编译函数声明。 (即,您永远无法向C编译器正确解释B是什么。)

所以,我在这里看到的唯一问题是你问题上[C]标签的含义是什么。您是否还需要某种与C的交叉兼容性?