【问题标题】:Why can't I call methods on unlinked DLL but can do this ? C++为什么我不能在未链接的 DLL 上调用方法但可以这样做? C++
【发布时间】:2019-11-28 11:46:51
【问题描述】:

所以我有 DLL Alice 和 DLL Bob。我不能互相调用方法。但只有一座桥。我可以从任一 DLL 分配一个指针(从现在开始我会说 the 指针)并在任一 DLL 中读取它。 但是,如果我将指针分配给 Alice 中定义的类的实例,我就不能从 Bob 调用它的方法,反之亦然。我也无法访问它的成员。它们根本没有链接(我收到 LNK 错误)。到目前为止一切顺利。

现在,问题来了。我在 Alice 和 Bob 中创建了相同的类(只是名称不同——我们称之为 MirrorClass)。当我将指针(两个 DLL 都可以访问它)分配给 Alice 中创建的 MirrorClass 实例时,我仍然无法从 Bob 调用它的方法。但我能做的是假装(显式转换)它是 Bob 的 MirrorClass 的一个实例,它会调用 Bob 的 MirrorClass 版本中定义的 Bob 的方法,一切仍然有效。即使它是 Alice 的 MirrorClass 实例。 显然,一旦我更改了 MirrorClass 的布局,它就会停止工作。

这怎么可能? 我想这可能与虚拟地址有关,或者每个 DLL 都有自己的地址空间。但是,对象只是指针,所以根据我的理解,你甚至不需要链接,所以我真的不理解这一点。

感谢您的每一个建议。

【问题讨论】:

  • 为什么不显示代码。
  • 任何 DLL 都可以使用任何其他 DLL。您只需要包含正确的定义并正确配置导入。
  • @MichaelChourdakis 这是一个庞大的代码库,很多项目,而且一团糟。所以我试着至少在文字上简化它。
  • @ElderBug 是的,但我认为我没有。它没有链接,没有导出,没有“LoadDll”之类的,只是包含标题以了解类布局。
  • 如果没有 LoadLibrary(“动态”DLL),则必须有导入,即使它们是隐式的。通常是 __declspec( dllimport ) 隐藏在宏后面。只要您没有相互依赖的标头,A 使用 B 和 B 使用 A 应该不是问题。 A 导入 B 和 B 导入 A。两者之一将在之前加载,但没关系。加载第二个时,第一个已经加载,可以解析导入。

标签: c++ object pointers dll linker


【解决方案1】:

如果你有一个指向类的指针,要使用类 vtbl 必须定义的方法(例如,使用抽象类(纯虚函数))。 例如,这就是 COM 在 Windows 中的工作原理。

现在,如果您在两个 DLL 和相同的编译器版本中获得相同的接口,第一个 vtbl 将与第二个相同,这使得从 A* 到 B* 的硬转换可以工作。

这当然是UB。它可能有效,也可能无效。

当加载到同一个进程中时,DLL 共享相同的地址空间,并且每个都可以使用其他任何一个。

【讨论】:

  • “vtbl 将是相同的”是什么意思,就像它指向完全相同的功能一样?另外,如果我们可以从 .h 中查看类布局并访问指针,为什么还需要链接器?
  • 如果你的 A 类有 2 个成员虚函数,当有人有 A* 指针时,有一个虚表用于在运行时查找这些函数。如果您对相同的 B 类执行两次,则您有两个可能相等的 vtbl,因此从 A* 转换为 B* 会起作用,尽管它会非常糟糕。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-22
  • 1970-01-01
  • 2021-03-24
  • 2013-07-09
  • 2013-02-01
  • 1970-01-01
  • 2010-09-27
相关资源
最近更新 更多