将dll链接到静态库并将其加载到链接到同一静态库的应用程序中

dre*_*wag 2 c++ linker shared-libraries static-libraries

我正在创建一个应用程序,它支持在运行时动态加载的dll形式的模块.代码按以下方式排列:

  • 核心 - 静态库

    这有一种加载共享库并调用"create"函数的机制,该函数返回一个新的Module对象(使用共享头).

  • 模块共享库(链接到核心静态库)

    此模块使用共享模块头,并使用核心库中的其他类(因此它与核心库链接的原因).它构建为包含静态库中的所有符号.

  • 测试应用程序可执行文件(链接核心静态库)

我变得时髦,看似零星的行为.它们总是在访问冲突中结束,但似乎我非常明确地设置的成员变量(整数)将在后面的函数中打印出来作为垃圾(我已经证实它们之前没有被删除).如果它们加载动态库(即使我从不调用create函数),这似乎只会发生.

我的主要问题是,这里存在危险吗,共享库中的符号会与可执行文件中的符号冲突(因为它们来自同一个静态库)并导致问题,即使它们来自完全相同的静态库?

小智 5

我无法代表Linux和OS X的行为,但在Windows上,以下是正在发生的事情.既然你说你也想在Windows上编译,这是相关的.

您遇到的问题是,您实际上核心中的所有内容都有多个版本.每个模块和应用程序本身都有自己的核心副本,并且共享它们的变量.这包括C运行时,因此跨模块边界的新/删除等事情充满了危险.

要验证这是发生了什么,请创建一个简单的测试:将核心中的全局设置为测试应用程序中的值,然后从动态加载的代码中尝试访问该全局并查看所获得的内容.我会打赌你会发现你的全球商店不会被反映出来!

解决方案:

1)使核心成为共享的动态库.这可能是也可能不适合您.

2)具备上述知识,非常谨慎地操作; 所有CRT和/或您自己的核心状态都不会被共享,因此您必须确保在模块边界的其他方面分配/销毁事物.

我自己的应用程序设计几乎与您的相同; 即一个静态库,其中包含应用程序和模块所需的共享代码,然后由应用程序核心加载动态加载的插件.

我为所有必须跨模块访问的共享核心状态所做的是,每个模块在加载后所做的第一件事就是将其"核心指针"设置为应用程序中核心库的实例化.这可确保所有模块都使用相同的数据.