7

我想要一个插件,名称更简单,可以在其他 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,但其他人呢?

4

3 回答 3

2

这应该可行,但有几个条件:

  • 如果您打算将 B 类的定义切换为其他内容,它将不起作用。您唯一可以更改的是 foo() 的定义。
  • 插件和加载程序都必须在二进制级别上就类 B 的接口达成一致。切换编译器(包括版本和一些标志)可以改变这个接口。
  • 您显然必须在 C++ 中转换 dlsym() 的返回值。
  • 在 C 中使用类是不可能的。
于 2013-01-27T15:44:30.410 回答
1

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

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

于 2013-01-27T16:05:46.147 回答
0

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

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

于 2013-01-27T19:19:16.317 回答