班级大小因模块 (DLL) 而异.如何以及为什么?

Class size is different across modules (DLLs). How and why?

本文关键字:而异 为什么 DLL 模块      更新时间:2023-10-16

我有两个Visual Studio 2015 C++项目,分别是ABA被编译为共享库,B使用它。它们都使用A中定义的类Foo

问题出现在B中的一行,如下所示:

auto p = std::make_shared<Foo>(3);

AccessViolationException.

我意识到ABFoo大小的识别方式不同,它使Foo的构造函数B越过Amake_shared分配的内存边界。使用 Visual Studio 的"监视"窗口,我可以看到当代码在模块中运行时sizeof(Foo)A为 1832,而当代码在模块中运行时,相同的监视条目给出的值为 1813B

我试图删除两个项目的所有中间文件和输出文件并重建整个解决方案,但从未提供帮助。

那么,单个类如何在不同的模块中以不同的大小出现呢?什么决定了类的内存布局?最后也是最重要的,我该如何解决问题?

除非满足以下条件之一,否则您不能从纯粹主义的角度推理对象大小(或布局(:

类型是标准布局类型。

关于构建的所有内容都是恒定的 - 特别是编译器标志、使用的编译器、编译器版本等。


最后也是最重要的,我该如何解决问题?

基本上你有2个选择。

使用标准布局类型确保其构建方式相同。出于这个原因,大多数公开可用的DLL或共享库接口在其接口中不使用高级类型(即非标准布局(,有些甚至保留与c兼容的代码(有时实际上与c兼容(。