我有一个特殊的用例,其中可执行文件需要导出某些符号,这些符号由运行时可执行文件加载的动态加载的DLL导入和使用。
可执行文件链接了一些静态库,这些静态库实际上具有导出的符号,而DLL使用这些静态库头来导入这些符号。
如果在可执行文件中未使用或未引用这些符号,则链接器会删除它们,因此它们不会被导出,因此在加载时不能用于DLL。
我分别使用--whole-archive和-force_load选项在GCC / clang上解决了这个问题。
Windows上的MSVC怎么样?我使用__declspec(dllexport)和__declspec(dllimport)在Windows上导出和导入符号。
编辑: 有关代码参考,您可以在此处找到代码:https://github.com/hunkabhicupid/exeexport
答案 0 :(得分:2)
Problem: On windows, STATIC LIB which contains an OBJ file that has a function marked __decl-spec(dll¬export) but if the same is not used in the EXE, function does not get exported from the EXE. On other platforms also we have the same problem BUT there we have compiler options like --whole-archive / -force_load, do make it work.
我想到的只有解决方案是不创建STATIC库,而是在可执行文件中包含所有代码(静态LIBS): 1.它适用于Windows 2.它适用于没有--whole-archive的Linux 3.它适用于没有-force_load的Mac OS X. 我们也不用担心2& 3包括死代码,exe膨胀等。
这是唯一的解决方案,直到连接器变得聪明并丢弃所有未使用的符号,除那些专门标记为外部消耗的符号,即标记为要导出的符号。
答案 1 :(得分:1)
dumpbin / exports {dll}是否正确显示出口?也许你应该尝试dumpbin / exports {import lib}?
基于迄今为止的信息,我猜测问题不在于符号不是导出的,而是构建顺序之一。如果在链接dll时得到“未解析的外部”,似乎你期望链接dll时链接器解析exe导出的符号,但是exe还没有构建。 (你可能将它连接到引用dll,所以它只在链接dll之后构建。)
实现它的一种方法是让dll LoadLibrary成为exe和GetProcAddress你想要的功能 - 但这实际上是一种人为的方式来实现你所追求的目标。如果这些符号是在静态库中定义的,为什么不同时使用exe和dll链接呢?