C++ 将dll链接到静态库,并将其加载到与同一静态库链接的应用程序中
我正在创建一个应用程序,它支持在运行时动态加载的DLL形式的模块。该守则的编排方式如下:C++ 将dll链接到静态库,并将其加载到与同一静态库链接的应用程序中,c++,linker,shared-libraries,static-libraries,C++,Linker,Shared Libraries,Static Libraries,我正在创建一个应用程序,它支持在运行时动态加载的DLL形式的模块。该守则的编排方式如下: 核心-静态库 这有一种加载共享库并调用“create”函数的机制,该函数返回一个新的模块对象(使用共享头) 模块共享库(与核心静态库链接) 此模块使用共享模块头,还使用核心库中的其他类(因此它与核心库链接)。它构建为包含静态库中的所有符号 测试应用程序可执行文件(与核心静态库链接) 我变得越来越古怪,而且似乎是零星的行为。它们总是以访问冲突告终,但似乎我非常明确地设置的成员变量(整数)将在以后的函数中作
- 核心-静态库 这有一种加载共享库并调用“create”函数的机制,该函数返回一个新的模块对象(使用共享头)
- 模块共享库(与核心静态库链接) 此模块使用共享模块头,还使用核心库中的其他类(因此它与核心库链接)。它构建为包含静态库中的所有符号
- 测试应用程序可执行文件(与核心静态库链接)
我的主要问题是,共享库中的符号是否存在与可执行文件中的符号冲突的危险(因为它们来自同一个静态库),并且即使它们来自完全相同的静态库,也会导致问题?我不能说Linux和OS X的行为,但在Windows上,下面就是正在发生的事情。因为你说你也希望在Windows上编译,这是相关的 您遇到的问题是,您实际上拥有多个版本的核心内容。每个模块和应用程序本身都有自己的核心副本,它们的变量不是共享的。这包括C运行时,所以像跨模块边界新建/删除这样的事情充满了危险 要验证这是正在发生的事情,请创建一个简单的测试:将核心中的一个全局设置为测试应用程序中的一个值,然后从动态加载的代码中尝试访问该全局并查看您得到了什么。我敢打赌,你会发现你在全球的店铺不会得到反映 解决方案: 1) 使core成为共享的动态库。这可能是你的选择,也可能不是 2) 在具备上述知识的情况下,极其小心地操作;所有CRT和/或您自己的核心状态都不会被共享,因此您必须确保在模块边界的自己一侧分配/销毁内容 我自己的应用程序的设计几乎与您的相同;ie是一个静态库,其中包含应用程序和模块所需的共享代码,然后动态加载由应用程序核心加载的插件
对于必须跨模块访问的所有共享核心状态,我所做的是,每个模块在加载后做的第一件事是将其“核心指针”设置为应用程序中核心库的实例化。这确保了所有模块都使用相同的数据。我目前在OS X上看到了这一点,但它也可以在Linux(Ubuntu)和Windows上编译。我现在将在Linux上尝试,看看是否发生了同样的情况。尝试在valgrind下运行您的程序以更好地诊断它。核心库是否使用任何不能复制的东西,例如命名文件或设备?不,核心库是完全独立的。问题似乎是我没有将核心库编译为独立于位置的代码。所有文件都有-fPIC参数,但静态库没有。这在Linux上导致了一个错误,但在OS X上没有。我不完全理解这是如何导致我所看到的显示的,所以我现在暂缓回答我自己的问题,以防其他人愿意更好地解释它。(同时,我正在等待,以确保我不会再看到问题)。