我有两个Visual Studio C ++项目,它们生成以下输出:
L.lib
E.exe
我想在 E.exe 和 L.lib 之间添加一个依赖项,而无需实际调用从 L.lib 导出的任何方法。 L.lib 导出单个函数:
__declspec(dllexport) unsigned foo();
然后在E.exe中,我具有以下编译单元:
// L.cpp
#pragma comment(lib, "L.lib")
extern unsigned foo();
问题在于,由于 E.exe 未使用foo
,因此对 L.lib 的依赖性得到了优化。在不实际执行任何代码的情况下,强制依赖 L.lib 的最佳方法是什么?我能想到的最好的方法是以下内容(从上方附加到 L.cpp ):
__declspec(dllexport) decltype(&foo) bar{ foo };
但是,以上结果导致在链接过程中生成其他文件(其中包括 E.lib ),并将公共方法添加到生成的 E.exe < / em>可执行文件。谁能想到一种更好的方法来强制将条目输入EXPORTS表?
我知道我可以禁用链接器优化以删除未使用的代码,但这会影响整个 E.exe ,而我不想这样做。
更多信息
我看到的问题是 E.exe 对第三方 L.lib (以及相关的 L.dll < / em>)(无法重定位)(例如,与/FIXED
选项链接)。在加载 L.dll 时, E.exe 加载的其他DLL占用了它需要加载的固定内存地址。我需要一种方法来确保 L.dll 尽可能早地加载,以防止另一个DLL占用 L.dll 才能正常运行所需的内存地址。
答案 0 :(得分:4)
只需采用无法优化的方式获取foo
的地址:auto volatile pFoo = &foo;
。它实际上没有被调用,但是编译器无法证明它未被调用,因此必须对其进行安全播放。
[编辑]
使用LTCG,Visual Studio显然比我想象的更具侵略性。添加pFoo=pFoo;
可以解决此问题。链接器映射:0003:0000037c ?pFoo@@3R6AXXZA 0040337c
答案 1 :(得分:1)
尽管MSalters回答在90%的情况下有效,但它始终无法始终从 E.exe 添加对 L.lib 的引用。另外,他的编辑建议要求修改可执行文件使用的函数的主体。我一直在寻找一种解决方案,只需要包含发送到链接器的其他源文件(编译单元)即可。
经过进一步调查,我确定以下代码完全可以做到这一点:
// L.cpp
#pragma comment(lib, "L.lib")
extern "C" unsigned foo();
#pragma comment(linker, "/include:_foo")
这迫使您知道foo
的名称错误,但是由于extern "C"
的声明,我的情况很容易确定。