c++ - 使用 MinGW 编译为带有一些 undefined reference 的 .dll

标签 c++ windows dll mingw

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

void bar();

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

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

但在 Unix 环境中,我可以毫无问题地将其编译为 .so 文件。然后我可以使用主机应用程序中的 dlopen(path, RTLD_NOW | RTLD_GLOBAL); 来加载库并将主机的符号与库的符号合并。如果宿主定义了 bar(),库将简单地调用该函数。

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

最佳答案

我想出了如何使用 MinGW 做到这一点。

通常,当链接 DLL 文件(例如 plugin.dll)时,您将符号列表导出到 libplugin.a,但在这种情况下,我实际上想将符号从主机可执行文件 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

这将使用 libhost.a 文件(在当前目录“.”中)构建 DLL。

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

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

关于c++ - 使用 MinGW 编译为带有一些 undefined reference 的 .dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39759060/

相关文章:

C++ boost : initializing endpoint after contructor

c++ - 我如何故意触发 fgets() 中的错误?

python - 在 Windows 上运行导入 xmlrpclib 的 Python 脚本?

windows - 让 Graphic Magick 检测 Ghostscript 以在 Windows 上阅读 pdf。如何将 WINDOWS CMD 上的 Ghostscript 调用名称更改为 'gs' ?

C# 使用导入的非强名称库构建强名称文件

c - 如何将 .so 文件链接到 .so 文件

windows - 获取 DLL 文件的 CLSID?

c++ - 一个端口Cave Story(NXEngine)如何到Native Client

python - 使用 SWIG 在 C++ Python 包装类中用二进制数据填充 char*

c# - Windows 似乎无法跟踪 .NET 应用程序