DLL 需要来自应用程序的符号(一个 class),它将 link 到

DLL needs symbols (a class) from the app it will link to

我无法获取到 link 的 DLL,这需要从应用程序导出 class,这个 DLL 将与之一起使用。 Visual Studio 2008 年,Windows 7.

我有一个小的示例 DLL 编译(实际上是默认的 MSFT DLL 项目),应用程序可以正确地使用 LoadLibrary()GetProcAddress()。我对 dllimport/dllexport 很有经验。使用 dumpbin /exports 对于发现与 GetProcAddress() 一起使用的损坏名称至关重要(MSFT 的默认空 DLL 包括一个没有 extern "C" 的示例函数),但这是一个已解决的问题。

下一步是让应用程序导出一个 class,DLL 需要子class。我以与通常相反的方式执行 dllimport/dllexport #define:应用程序编译时的特殊符号用 dllexport 和 non-app 代码标记 class(例如DLL) 使用 header,没有特殊符号,获得 dllimport 规范。 .exe 文件上的 dumpbin /exports 准确地显示了这个 class 的(损坏的)符号被导出,没有其他符号,正如预期的那样。

下一步是让 DLL 包含 header 并创建导出的 object 类型的 object(作为 baby-step 实际子class正在处理它)。编译正常,但 linker 显示错误:

DynTest.obj : error LNK2019: unresolved external symbol "public: __thiscall Test::Test(class Toast*,double)" (??0Test@@QAE@PAVToast@@N@Z) referenced in function "public: __thiscall CDynTest::CDynTest(void)" (??0CDynTest@@QAE@XZ)

好的,这并不让我吃惊,因为我知道在 WIN32 上我需要在 link 时间提供 DLL 来制作 DLL,这与我通常使用的 Unix 不同。由于 Windows 似乎对 DLL 和可执行文件的处理方式有点相似,因此我尝试在 Properties->Configuration Properties->Linker->Input->Additional Dependencies 添加 .exe。这得到一个错误,看起来像 LINK.EXE 没有 auto-detect 它被赋予了 .exe:

T:\mypath\MyBinary.exe : fatal error LNK1107: invalid or corrupt file: cannot read at 0x348

然后我尝试添加定义此 class 的 object 文件...这似乎被 linker 理解,并且可能成功地满足了 DLL 的需要到 link,但现在显示此文件所依赖的无数其他符号。

所以我考虑过重构应用程序,使其大部分位于 DLL 或 LIB 中,这样我就可以将其作为 "Additional Dependencies" 提供给我真正担心的 DLL。但这似乎是严厉的。这是我唯一的选择吗?

调用 dumpbin /exports 会为您提供 exe 导出的损坏名称列表。您需要创建一个包含这些名称的模块定义文件 (.def):

EXPORTS
   @d3d_some_fancy_mangedled_method_1
   @d3d_some_fancy_mangedled_method_2
   ...

请注意,它基本上是删除了第一列的 dumpbin 输出。 然后使用 lib 工具从模块定义文件生成导出库:

LIB /DEF:prog.def /NAME:prog.exe /MACHINE:x86

最后,您 link 将导出库 prog.lib 生成到您的应用程序中。 /MACHINE 选项应该与您的可执行文件相匹配。请注意,您不需要 link 或以任何方式使用程序可执行文件 link 它,仅使用导出库。