我正在将大型C ++应用程序从Linux(gcc)移植到Windows(Visual C ++ 2008),并且遇到插件的链接器问题。在Linux上这不是问题,因为.so支持运行时符号查找,但dll似乎不支持这一点。
一些背景资料: 托管脚本环境的应用程序(主机)提供插件接口(通过脚本API调用在运行时加载的共享库),允许扩展主机和脚本API,而无需重新编译主机应用程序。在Linux上,这只是在插件源中包含宿主应用程序的标题,但在Windows上我收到了链接器错误。我不确定我需要链接到Visual C ++来解析这些符号。
我们的一个依赖项(开源,LGPL)具有预处理器声明,用于将__declspec(dllexport)和__declspec(dllimport)插入其标头中。一些先前的研究表明我可能也必须这样做,但我想在修改一大堆核心标题之前确定。 (我以前能够在MinGW上工作,但我们已经决定支持Visual Studio是这类商业项目的必要条件。)
我的问题,简而言之:如何在Visual C ++中将运行时加载的dll与主机exe相关联?
编辑:为了通过示例澄清问题,我在宿主应用程序中有一个类 Object ,它表示脚本可以访问的对象的基本类型。在我的插件中,我有许多类,它们扩展 Object 来执行其他功能,例如集成网络支持或新的可视元素。这意味着我的dll必须与主机exe中的符号链接,我不知道该怎么做。
答案 0 :(得分:5)
“运行符号查找”是什么意思?您是指使用dlopen
和dlsym
以及so on动态加载库吗? equivalents in Windows被称为LoadLibrary
和GetProcAddress
。
在Windows中,您不从可执行文件导出符号。您应该只从dll导出它们。解决问题的正确方法是重新架构,以便导出的符号位于可执行文件和其他插件dll可以链接的dll中。
答案 1 :(得分:1)
你不能,轻松。 Windows加载程序不是为了从EXE中导出符号而将它们绑定到DLL中的符号。
我看到的一种模式是DLL导出EXE调用的某个函数。它将一个结构作为参数,该结构包含EXE中用于调用DLL的函数的地址。
答案 2 :(得分:1)
正如1800信息所说,不要那样做。将对象移出可执行文件并进入“第三个”DLL。将插件和可执行文件链接起来。
答案 3 :(得分:1)
我一直在实现相同的功能,构建一个在Linux和Windows下构建的插件库。
Linux下的解决方案是在gcc命令行中使用-rdynamic选项。这会导出主可执行文件中的所有符号,以便插件可以在加载时找到它们。
在Windows下,解决方案是在你希望dll使用的exe中定义那些函数的前面添加__declspec(dllexport)。编译将为要链接的dll创建.lib文件。当然可以在Visual Studio 2008下工作。 相关文章:https://stackoverflow.com/a/3756083/1486836