使用MinGW编译一些未定义的引用.dll

时间:2016-09-28 23:17:46

标签: c++ windows dll mingw

我听说所有Windows .DLL 必须包含它引用的每个符号的定义,因此像这样的.DLL文件永远不会编译,因为它没有实现bar()。 / p>

void bar();

__declspec(dllexport)
void foo() {
    bar();
}

我认为类比是.DLL本质上是具有不同入口点的可执行文件,因此它们必须将所有引用定义为可执行文件。

但是在Unix环境中,我可以将它编译成.so文件,没有任何问题。然后我可以使用主机应用程序中的dlopen(path, RTLD_NOW | RTLD_GLOBAL);来加载库并将主机的符号与库的符号合并。如果主机定义bar(),则库将只调用该函数。

我不能只是将所有内容重新定义到.DLL文件中,因为在我的应用程序中,库使用来自主机的数千个符号。使用MinGW或可能的Visual C ++,是否真的没有办法使用主机中的符号,在.DLL中保留未定义并在加载时合并它?我也不想在.DLL中设置数千个回调函数,因为使用C ++方法会变得很困难。

1 个答案:

答案 0 :(得分:3)

我想出了如何使用MinGW。

通常,在链接DLL文件(例如plugin.dll)时,会将符号列表导出到libplugin.a,但在这种情况下,我实际上想要从主机可执行文件中导出符号{{1转到host.exe

libhost.a

这将生成符号列表,您可以在构建插件时链接到该列表。

x86_64-w64-mingw32-g++ -o host.exe host.cpp -Wl,--out-implib,libhost.a

这使用x86_64-w64-mingw32-g++ -shared -o plugin.dll plugin.cpp -L. -lhost文件(在当前目录“。”中)构建DLL。

现在,使用libhost.a填充主机代码有点烦人,因此您可以添加__declspec(dllexport)链接器标志。 出于某种原因,在执行此操作之后似乎不需要--export-all-symbols属性,但我不知道为什么。 因此,您可以使用

编译主机

_declspec(dllimport)