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

发布于 2024-10-21 00:05:47 字数 617 浏览 1 评论 0原文

我有一个 DLL one.dll,它使用通过 class __declspec(dllexport)two.dll 导出的类 TwoClass >。我希望 one.dlltwo.dll 使用 /delayload,但我收到链接错误:

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;在调试版本中它可以工作。 (我不知道 Release 和 Debug 在 vtable 导出方面有什么区别,也找不到任何编译器开关或编译指示来控制它。)

如何将 /delayload 与 DLL 一起使用在发布版本中导出这样的类?

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:

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.)

How can I use /delayload with a DLL that exports classes like this in a Release build?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

十秒萌定你 2024-10-28 00:05:47

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

我成功实现了延迟加载
通过禁用对发布版本的优化来工作
使用 SomeClass 类的翻译单元 - 不知何故它拿走了
对导出的 vtable 的依赖。

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.

恋竹姑娘 2024-10-28 00:05:47

检查 one.dll 是否包含包含 TwoClass.hxx 但实际上并未使用它的源文件。此外,检查 TwoClass 是否满足编译器生成方法的条件(请参阅 自动生成条件)。

就我而言,我实际上不需要编译器生成的复制构造函数,也不需要 TwoClass 的赋值运算符,因此我在 private: 部分中声明了它们,而没有提供定义。这导致了 one.dll 的构建错误,从而引导我找到了不必要地包含 TwoClass.hxx 的源文件。删除不必要的包含后,我能够在打开优化和 /delayload 的情况下进行编译和链接。

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

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).

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.

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.

可是我不能没有你 2024-10-28 00:05:47

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

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.

财迷小姐 2024-10-28 00:05:47

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

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__));

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.

class __declspec(dllimport) VidExpInternal : public VidExpBase
{
public:
    VidExpInternal(TCHAR* msg=_T(""), int ln=__LINE__, TCHAR* filechar=_T(__FILE__));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文