windows 如何对导出 C++ 类的 DLL 使用延迟加载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5232912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use delay loading with a DLL that exports C++ classes
提问by RichieHindle
I have a DLL one.dll
that uses a class TwoClass
exported from two.dll
via class __declspec(dllexport)
. I'd like one.dll
to use /delayload
for two.dll
, but I get a link error:
我有一个one.dll
使用TwoClass
从two.dll
via导出的类的 DLL class __declspec(dllexport)
。我想one.dll
使用/delayload
for two.dll
,但出现链接错误:
LINK : fatal error LNK1194: cannot delay-load 'two.dll' due to import
of data symbol '"__declspec(dllimport) const TwoClass::`vftable'"
(__imp_??_7TwoClass@@6B@)'; link without /DELAYLOAD:two.dll
That's in a Release build; in a Debug build it works. (I don't know what the difference is between Release and Debug in terms of vtable exports, nor can I find any compiler switches or pragmas to control it.)
这是在发布版本中;在调试版本中它可以工作。(我不知道 Release 和 Debug 在 vtable 导出方面有什么区别,也找不到任何编译器开关或编译指示来控制它。)
How can I use /delayload
with a DLL that exports classes like this in a Release build?
如何/delayload
与在发布版本中导出此类的 DLL 一起使用?
采纳答案by davka
Have a look here, seems that the person had exactly the same problem and found a workaround
看看这里,似乎该人遇到了完全相同的问题并找到了解决方法
I managed to get the delay loading to work in release build by disabling the optimizations on the translation unit that was using SomeClass class - somehow it took away the dependency on exported vtable.
通过禁用对使用 SomeClass 类的翻译单元的优化,我设法使延迟加载在发布版本中工作 - 它以某种方式消除了对导出的 vtable 的依赖。
回答by ThM
Check if one.dll contains a source file that includes TwoClass.hxx but does not actually use it. In addition check whether TwoClass meets the conditions for compiler generated methods (see conditions for automatic generation).
检查 one.dll 是否包含包含 TwoClass.hxx 但实际上并未使用它的源文件。另外检查 TwoClass 是否满足编译器生成方法的条件(参见自动生成条件)。
In my case I actually didn't need a compiler generated copy ctor nor the assignment operator for TwoClass so I declared them in the private:
section without providing a definition. That created build errors for one.dll, which guided me to the source files that unnecessarily included TwoClass.hxx. After removing the unnecessary includes I was able to compile and link with optimization turned on and with /delayload.
在我的例子中,我实际上不需要编译器生成的复制构造函数,也不需要 TwoClass 的赋值运算符,所以我在private:
没有提供定义的部分中声明了它们。这为 one.dll 造成了构建错误,引导我找到了不必要地包含 TwoClass.hxx 的源文件。删除不必要的包含后,我能够在打开优化和 /delayload 的情况下编译和链接。
I assume that the unnecessary #include
statements misguided the optimizer to copy the compiler generated methods for TwoClass into the .obj files to be linked into one.dll even though they were not used in these .obj files. These unnecessary compiler generated methods for TwoClass seem to prevent a link with /delayload.
我假设不必要的#include
语句误导了优化器将编译器生成的 TwoClass 方法复制到要链接到 one.dll 的 .obj 文件中,即使它们没有在这些 .obj 文件中使用。这些不必要的编译器为 TwoClass 生成的方法似乎阻止了与 /delayload 的链接。
回答by TarmoPikaro
I had exactly same problem with class which contained inline implementation for exported class.
我对包含导出类的内联实现的类有完全相同的问题。
class __declspec(dllimport) VidExpInternal : public VidExpBase
{
public:
VidExpInternal(TCHAR* msg=_T(""), int ln=__LINE__, TCHAR* filechar=_T(__FILE__)) :
VidExpBase (msg,ln,filechar) {}
I've moved inline implementation to .cpp file - after that everything worked out smoothly.
我已将内联实现移至 .cpp 文件 - 之后一切顺利。
class __declspec(dllimport) VidExpInternal : public VidExpBase
{
public:
VidExpInternal(TCHAR* msg=_T(""), int ln=__LINE__, TCHAR* filechar=_T(__FILE__));
回答by 0xC0000022L
Define a factory function that hands out instances of a class, much like in COM. This also requires that the interface(s) of the classes be public, but that's a given as well when someone imports a class.
定义一个分发类实例的工厂函数,就像在 COM 中一样。这也要求类的接口是公共的,但是当有人导入一个类时,这也是给定的。