繁体   English   中英

共享库中的类的构造函数是否已导出?

[英]Is the constructor of a class from a shared library exported?

我有一个包含类Foo的共享库lib.so 我正在动态加载(在UNIX上为dlopenlib.so 加载后,我想创建一个Foo的实例。
我可以简单地使用new运算符创建Foo的对象,还是必须创建放置在lib.so中的导出工厂方法,以便为我创建该对象?

实际上,问题是是否可以导出Foo的构造函数,以及是否可以简单地使用new运算符调用它。 我认为默认情况下会导出UNIX上共享库中的所有类和方法,而不必像在Windows dll上那样显式导出它们。

除了隐藏创建(可能初始化) Foo对象的方式之外,在创建共享库中包含的类的对象时,还有其他使用工厂方法的原因吗?

基本答案是肯定的。 然而,细节在于魔鬼。 在Windows上,使用Microsoft C ++编译器,默认情况下不会为DLL导出所有符号,无论它们是方法,变量等。 您需要显式导出函数,类和/或全局变量。 我相信Borlands编译器也是如此(我可能是错误的)。

使用GCC以前,所有内容默认情况下都是导出的,您无法真正控制它。 几年前,这种情况发生了变化,增加了一个属性(我不记得确切的名字,但是它的工作方式类似于等效的Microsoft __declspec(dllexport))。

因此,如果您定义一个类并将其标记为已导出(无论您选择这样做),它将被导出构造函数。 但是,正如先前的海报所提到的,由于C ++的性质,符号的名称会根据您使用的编译器以及有时的C ++编译器版本而变化。 这不一定是问题,它取决于您想如何使用事物,但这确实意味着您必须意识到这一点。

这种方法存在问题。 特别是,当对库和程序使用同一编译器的不同版本时,不能保证类成员函数具有相同的符号名。

因此,请使用工厂方法和不透明的C指针类型:

// .cpp file
class Foo { ... };

// .h file
struct FooHandle;

#ifdef __cplusplus
extern "C"
{
    FooHandle* constructFoo(...);
    void releaseFoo(FooHandle*);
    int someFooMethod(FooHandle*, int param1, ...);
}
#endif

导出共享库时,请始终使用C函数和不透明的指针类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM