如何使用导出C ++类的DLL进行延迟加载

时间:2011-03-08 13:11:04

标签: c++ windows visual-studio dll vtable

我有一个DLL one.dll,它使用从TwoClass通过two.dll导出的类class __declspec(dllexport)。我希望one.dll/delayload用于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

这是在发布版本中;在Debug构建中它可以工作。 (我不知道在vtable导出方面Release和Debug之间有什么区别,我也找不到任何编译器开关或pragma来控制它。)

如何将/delayload与在Release版本中导出类似的类的DLL一起使用?

4 个答案:

答案 0 :(得分:5)

看看here,似乎该人遇到了完全相同的问题,并找到了解决方法

  

我设法得到延迟加载   通过禁用优化来在发布版本中工作   正在使用SomeClass类的翻译单元 - 不知怎的,它已经消失了   对导出的vtable的依赖。

答案 1 :(得分:1)

检查one.dll是否包含包含TwoClass.hxx的源文件但实际上并未使用它。另外检查TwoClass是否满足编译器生成方法的条件(参见conditions for automatic generation)。

在我的情况下,我实际上不需要编译器生成的复制ctor,也不需要TwoClass的赋值运算符,所以我在private:部分声明了它们而没有提供定义。这为one.dll创建了构建错误,引导我访问不必要包含TwoClass.hxx的源文件。删除不必要的包含后,我能够编译并链接优化打开和/ delayload。

我假设不必要的#include语句误导了优化器将编译器生成的TwoClass方法复制到.obj文件中以链接到one.dll,即使它们没有在这些.obj文件中使用。这些不必要的编译器为TwoClass生成的方法似乎阻止了与/ delayload的链接。

答案 2 :(得分:0)

定义一个分发类实例的工厂函数,就像在COM中一样。这也要求类的接口是公共的,但是当有人导入类时,这也是一个给定的。

答案 3 :(得分:0)

我对包含导出类的内联实现的类有完全相同的问题。

class __declspec(dllimport) VidExpInternal : public VidExpBase
{
public:
    VidExpInternal(TCHAR* msg=_T(""), int ln=__LINE__, TCHAR* filechar=_T(__FILE__)) :
        VidExpBase (msg,ln,filechar) {}

我已将内联实现移至.cpp文件 - 之后一切顺利完成。

class __declspec(dllimport) VidExpInternal : public VidExpBase
{
public:
    VidExpInternal(TCHAR* msg=_T(""), int ln=__LINE__, TCHAR* filechar=_T(__FILE__));