问题 从C调用的C ++共享库


我有一个用C ++编写的共享库。它导出一个可见的界面 extern "C" 创建,销毁和操纵不透明类型的函数。

现在,我想要一个使用这个库的纯C程序。

我可以这样做(独立平台)吗?如果,C ++运行时和C ++静态对象何时初始化 main 是不是用C ++编写的?


12491
2017-12-23 14:15


起源



答案:


初始化阶段取决于平台。 对于Linux,动态加载的库可以具有自动调用的特殊声明符号 dlopen() 加载库时

请参阅联机帮助页 dlopen(3), 部分 过时的符号init()和fini() 了解更多信息。

静态初始值设定项隐式标记为 __attribute__((constructor)),因此通常在加载共享库时,不必执行任何特殊操作。我怀疑在其他平台上这是相同或相似的。


5
2017-12-23 14:30



附录。 (glibc :) init / fini由运行时环境(crtS.o)提供,用于初始化静态持续时间对象和调用标记为__attribute __((构造函数)的函数),因此自行覆盖init / fini会导致问题,包括因双重符号定义而纾困。 - jørgensen
@jørgensen:这可能是他们被弃用的原因吗? - onitake


答案:


初始化阶段取决于平台。 对于Linux,动态加载的库可以具有自动调用的特殊声明符号 dlopen() 加载库时

请参阅联机帮助页 dlopen(3), 部分 过时的符号init()和fini() 了解更多信息。

静态初始值设定项隐式标记为 __attribute__((constructor)),因此通常在加载共享库时,不必执行任何特殊操作。我怀疑在其他平台上这是相同或相似的。


5
2017-12-23 14:30



附录。 (glibc :) init / fini由运行时环境(crtS.o)提供,用于初始化静态持续时间对象和调用标记为__attribute __((构造函数)的函数),因此自行覆盖init / fini会导致问题,包括因双重符号定义而纾困。 - jørgensen
@jørgensen:这可能是他们被弃用的原因吗? - onitake


我可以这样做(独立平台)吗?

库加载是依赖于平台的操作。

何时初始化C ++运行时和C ++静态对象   如果main不是用C ++编写的?

无所谓。它们将在主要输入之前初始化。


4
2017-12-23 14:32



好吧,之后仍然可以(手动)加载库 main 进入了。而且“They will be initialized before the main is entered. “这是一种误解。它的实现定义了静态对象的初始化是否发生在之前 main 输入,或在首次使用之前的任何时间输入。但是出于所有实际目的,是的,它们之前已初始化 main,或者在加载库之后。 - jweyrich


通常,共享库系统有自己的入口点,而不是 main 但DLL有一个 DLLMain 其中实现可以放这样的代码。但是,在一般情况下,它不属于您的业务,它是您用于处理此问题的任何编译器的工作。


1
2017-12-23 14:37