【问题标题】:C++ shared library called from C从 C 调用的 C++ 共享库
【发布时间】:2011-12-23 14:15:41
【问题描述】:

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

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

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

【问题讨论】:

    标签: c++ c shared-libraries portability


    【解决方案1】:

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

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

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

    【讨论】:

    • 附录。 (glibc:) init/fini 由运行时环境 (crtS.o) 提供,用于初始化静态持续时间对象和调用标记为 __attribute__((constructor)) 的函数,因此自行覆盖 init/fini 可能会导致问题,包括由于双重符号定义而退出。
    • @jørgensen:这可能是它们被弃用的原因吗?
    【解决方案2】:

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

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

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

    没关系。它们将在进入 main 之前被初始化。

    【讨论】:

    • 好吧,在main 进入后,仍然可以(手动)加载库。而“They will be initialized before the main is entered.”是一种误解。静态对象的初始化是在输入main 之前发生还是在第一次使用之前发生,这是由实现定义的。但是出于所有实际目的,是的,它们是在 main 之前初始化的,或者是在加载库之后。
    【解决方案3】:

    通常,共享库系统有自己的入口点来完成这项工作,而不是main,但DLL 有一个DLLMain,实现可以在其中放置此类代码。但是,在一般情况下,这与您无关,而是您用来处理此问题的任何编译器的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      相关资源
      最近更新 更多