Visual Studio 强制库导入 C++

Visual Studio Force Library Import C++

我有两个 Visual Studio C++ 项目,生成以下输出:

L.lib
E.exe

我想在 E.exeL.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[=52 的依赖=] 被优化掉了。在不实际执行任何代码的情况下强制依赖 L.lib 的最佳方法是什么?我能想到的最好的是以下内容(从上面附加到 L.cpp):

__declspec(dllexport) decltype(&foo) bar{ foo };

但是,上述结果会在链接过程中生成额外的文件(E.lib,以及其他),并向 EXPORTS 添加 public 方法结果 E.exe executable 的 table。谁能想出更好的方法来强制进入 EXPORTS table?

我知道我可以禁用链接器优化以删除未使用的代码,但这会影响整个 E.exe,我不想这样做.

更多信息

我看到的问题是 E.exe 对第三方有传递依赖性 L.lib(以及关联的 L.dll),它是非 relocatable(例如,与 /FIXED 选项链接)。到L.dll加载时,它需要加载的固定内存地址已经被E.exe加载的其他DLL占用了。我需要一种方法来确保尽早加载 L.dll,以防止另一个 DLL 占用 L.dll[ 的内存地址=52=] 需要才能正常运行。

直接把foo的地址用无法优化掉的方式取下来:auto volatile pFoo = &foo;。它实际上并没有被调用,但是编译器不能证明它没有被调用所以它必须安全地使用它。

[编辑] Visual Studio 显然比我想象的更激进,使用 LTCG。添加 pFoo=pFoo; 修复它。链接器映射:0003:0000037c ?pFoo@@3R6AXXZA 0040337c

虽然 MSalters 的答案在 90% 的情况下都有效,但它并不总是从 E.exe[ 添加对 L.lib 的引用=21=]。此外,他的编辑建议需要修改可执行文件使用的函数体。我一直在寻找一个只需要包含发送到链接器的附加源文件(编译单元)的解决方案。

经过进一步调查,我确定以下代码正是这样做的:

// L.cpp
#pragma comment(lib, "L.lib")
extern "C" unsigned foo();
#pragma comment(linker, "/include:_foo")

这迫使您知道 foo 的损坏名称,但由于 extern "C" 声明,我的情况很容易确定。