【发布时间】:2017-11-17 02:14:36
【问题描述】:
我无法获取要链接的 DLL,它需要从应用程序导出的类,该类将用于此 DLL。 Visual Studio 2008,Windows 7。
我有一个小的示例 DLL 编译(实际上是默认的 MSFT DLL 项目),应用程序可以正确使用 LoadLibrary() 和 GetProcAddress()。我对 dllimport/dllexport 很有经验。使用 dumpbin /exports 对于发现与 GetProcAddress() 一起使用的错位名称至关重要(MSFT 的默认空 DLL 包括一个没有 extern "C" 的示例函数),但这是一个已解决的问题。
下一步是让应用导出一个 DLL 需要子类化的类。我执行 dllimport/dllexport #define 的操作与往常相反:编译应用程序时的特殊符号使用该标头使用 dllexport 和非应用程序代码(例如 DLL)标记类,没有特殊符号, 得到一个 dllimport 规范。 .exe 文件上的dumpbin /exports 准确地显示了正在导出的此类(损坏的)符号,没有其他符号,正如预期的那样。
下一步是让 DLL 包含标头并创建导出对象类型的对象(作为实际继承它的小步骤)。编译正常,但链接器显示错误:
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 上我需要在链接时提供 DLL 来生成 DLL,这与我通常的 Unix 不同。由于 Windows 似乎对 DLL 和可执行文件的处理方式有点相似,因此我尝试在 Properties->Configuration Properties->Linker->Input->Additional Dependencies 中添加 .exe。这会得到一个错误,看起来像 LINK.EXE 没有自动检测到它被赋予了 .exe:
T:\mypath\MyBinary.exe : fatal error LNK1107: invalid or corrupt file: cannot read at 0x348
然后我尝试添加定义此类的目标文件...链接器似乎可以理解,并且可能成功满足了 DLL 的链接需求,但现在显示了该文件所依赖的无数其他符号.
所以我考虑重构应用程序,使其大部分位于 DLL 或 LIB 中,这样我就可以将其作为“附加依赖项”提供给我真正担心的 DLL。但这似乎是严厉的。这是我唯一的选择吗?
【问题讨论】:
-
您是否希望能够更改 EXE 并使 DLL 使用新版本的超类?我不认为这是可能的。它似乎也不是超类的正确位置......应用程序使用 DLL,而不是相反。将超类放入 DLL 中。
-
我希望重建应用程序并使用旧的 DLL,但不要更改 DLL 继承的类。 API 在这方面将保持稳定。符号不会改变(或重新排序,或在它们之前添加新符号,如果这些是 MSFT 无法处理的)。我同意这些要求可能看起来令人困惑,但这些是这个项目的要求。考虑允许用户自定义应用程序基类的 DLL。现在:我当然可以实现不同的技术实现逻辑模型。但模型并没有改变。
标签: c++ dll visual-studio-2008 windows-7 dllimport