使用静态构造函数链接到dll时如何解决未解析的外部符号?

How to resolve unresolved external symbol when linking against dll with static constructors?

提问人:kbzombie 提问时间:3/25/2019 最后编辑:kbzombie 更新时间:3/26/2019 访问量:124

问:

我正在用一些实用程序、工具等在 D 中构建一个 dll。我可以成功编译一个基本的 dll 并测试程序以在视觉 D 中使用它,没有任何问题。我熟悉创建和使用dll的过程。尤其是静态链接。但是,如果 dll 中的模块具有静态 this(),或者导入具有静态 this() 的模块,则 dll 将编译,但您构建的任何使用它的程序都将失败,并出现无法解析的foo.bar.__ModuleInfo。

错误 LNK2001:未解析的外部符号“dtoolbox.dtoolboxdllmain.__ModuleInfo”(__D8dtoolbox15dtoolboxdllmain12__ModuleInfoZ)

在这种情况下,我的 dllmain 模块 dtoolbox.dtoolboxdllmain 导入 core.runtime,它有一个静态的 this(),所以我得到这个错误。如何解决此问题?静态模块构造函数做了什么导致这种情况?只要没有静态构造函数,一切正常。

[编辑]导入 core.runtime 不是问题,而是模块自己的静态 this(),而不是 core.runtime 的静态 this()。

DLL 链接器 d unresolved-external

评论

1赞 Adam D. Ruppe 3/25/2019
源导入文件是什么样子的?您是导入原始的 .d 文件,还是剥离了函数体的文件(又名 .di 文件)?
1赞 kbzombie 3/26/2019
亚当,你回答了这个问题。出于某种原因,我正在导入原始的 .d 文件,在本例中为带有 dllmain 的文件。我什至不需要导入,因为它没有导出任何可用的功能。我从测试项目中删除了导入,一切正常。我做了一些测试,发现你不能直接用静态this()导入模块,我想这就是.di的用途?
0赞 Adam D. Ruppe 3/26/2019
是的,di 文件(实际上只是一个 D 文件;编译器对它们的态度完全相同,但按照惯例,当主体被剥离时,我们将其命名为 .di)允许您向调用者隐藏这些内部细节。你可以取出模块 ctor/dtor(在 dll 内部处理)、大多数函数体、大多数私有成员 - 隐藏除最低要求接口之外的任何内容。顺便说一句,你可能想写这篇文章作为对自己的回答,供未来的读者使用。

答:

2赞 kbzombie 3/26/2019 #1

解决方案是避免将带有 dll 的静态 this() 和 & static ~this() 的模块导入到使用 dll 的程序的模块中。(在这种情况下,dllmain模块被导入,完全没有理由,我的错误)并不是说 dll 不能拥有它们,它们只需要在编译 dll 时存在于某个文件中。我发现将它们写在与 dllmain 相同的模块中很方便,因为这个文件永远不需要被使用 dll 的程序引用/导入。