Visual Studio Force库导入C ++

时间:2018-08-21 01:33:39

标签: c++ visual-studio dll visual-studio-2015 linker

我有两个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 才能正常运行所需的内存地址。

2 个答案:

答案 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"的声明,我的情况很容易确定。