首页 > 解决方案 > 关于winrt Demo对象的大小

问题描述

我很好奇一个非常简单的 Demo 对象的大小,所以,我正在编写以下代码

#include <windows.h> #include "winrt/base.h" #include <iostream> #pragma comment(lib, "windowsapp") /* cl /nologo /await /std:c++latest /wd4002 /EHsc base_so.cpp */ using namespace std; using namespace winrt; using namespace winrt::impl; struct IDemo; template <typename D> struct consume_IDemo { void hello(); }; template <> struct consume<IDemo> { template <typename D> using type = consume_IDemo<D>; }; template <typename D> void consume_IDemo<D>::hello() { WINRT_SHIM(D)->hello(); } struct WINRT_EBO __declspec(uuid("3A44B7CC-9CB6-4512-8CAD-6400E662D865")) IDemo : Windows::Foundation::IInspectable, consume_t<IDemo> { IDemo(std::nullptr_t = nullptr) noexcept {}; }; template <> struct abi<IDemo> { struct type : IInspectable { virtual HRESULT hello() = 0; }; }; template <typename D> struct produce<D,IDemo> : produce_base<D,IDemo> { HRESULT hello() override { shim().hello(); return S_OK; } }; struct Demo : implements<Demo,IDemo> { Demo() { cout << "sizeof Demo 0x" << hex << sizeof(*this) << dec << endl; cout << "sizeof m_references 0x" << hex << sizeof(std::atomic<std::conditional_t<1, uintptr_t, uint32_t>>) << dec << endl; cout << "is_composing " << is_composing << endl; cout << "outer " << outer() << endl; } HRESULT hello() { cout << __FUNCTION__ << endl; return S_OK; } }; int main() { Demo d; }

输出是

sizeof Demo 0x18
sizeof m_references 0x8
is_composing 0
outer 0000000000000000

我认为 Demo 的 sizeof 应该是 0x10(64 机器): sizeof(m_references)+sizeof(produce<Demo,IDemo>) ,那么,额外的 8 个字节是多少?非常感谢!

标签: c++c++-winrt

解决方案


它是填充或 v 表。也许两者...

编译器可能会为每个声明了至少一个虚拟方法的基类插入一个 v-table 指针。(顺便说一句,当您从具体类到非第一个基类执行 C-cast、static_cast 或 dynamic_cast 时,编译器会将指针值更改为基类或其 v 表的指针值。 )

让我们分解一下。

Demo继承自implements<Demo,IDemo>

implements定义如下:

struct implements : impl::producers<D, I...>, impl::base_implements<D, I...>::type
{

现在我们进入 WinRT 噪音。但它似乎确实暗示了多重继承。但它只是更容易打破它调试器......你去。第一个 vtable 用于 IUnknown。另一个与 IInspectable 有关。

所以这是有道理的。每个 v-table 是一个 8 字节的指针。m_references 也是 8 个字节。 8+8+8 = 24 = 0x18

在此处输入图像描述


推荐阅读