c++ - 关于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 个字节是多少?非常感谢!
解决方案
它是填充或 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
推荐阅读
- php - 如何在产品页面 Magento 2 上显示属性组名称
- scala - 如何使用 spark scala 根据日期将行拆分为多行?
- webpack - 在 webpack 4 中拆分块
- html - 如何制作位置固定在第二个和标签下的弹出元素?
- xcode - 使用 XCODE 构建时出错
- java - Flink 中的 windowAll 算子是否会将并行化缩减为 1?
- ruby-on-rails - Heroku:通过 rake 任务解压 Gzip 文件失败
- swift - Codable 类中的可编码变量
- java - javax.xml.transform.Transformer 未将数据写入 Linux 中的文件
- react-native - JSON 解析错误:无法识别的令牌'<' - react-native