【问题标题】:Struct/Class metadata for object representation and managed/unmanaged interaction用于对象表示和托管/非托管交互的结构/类元数据
【发布时间】:2021-07-13 09:10:59
【问题描述】:

我知道有很多类似的问题,但我想了解非常具体的方面,而这些方面从未在任何地方提及。在这两种情况下:托管(在这种情况下为 NET 运行时)和本机/非托管(c、cpp 等)

取自这里: https://adamsitnik.com/Value-Types-vs-Reference-Types

第一个不仅没有被掩盖而且甚至没有提及的问题是您的代码/运行时应该如何知道您正在处理的结构类型?如果 struct 只是将所有数据打包在一起,那么关于它是什么类型的 struct 的元数据在哪里?好的,在托管 .NET 运行时和二进制文件的情况下,它更容易,它是 IL 的一部分,但是本机二进制代码呢?它被剥离 100%,如果您打开它进行文本阅读,那么二进制文件中没有函数或结构名称。如果没有结构元数据,您将如何知道运行时收到的结构以及如何处理/解析它?指针只指向内存,但没有存储结构和成员。至少类可以通过它拥有的额外数据(对象头和方法表)来识别。

当您从非托管/本机空间接收结构数据时,事情会变得更加更加混乱。您需要将该数据嵌入到结构中,否则您怎么知道收到了什么?而且我甚至无法开始理解*这对于诸如类之类的东西是如何工作的,因为它们要复杂千倍。您甚至如何从非托管空间返回课程?

【问题讨论】:

    标签: c# c++ memory


    【解决方案1】:

    如果结构只是将其所有数据打包在一起,那么关于它是什么类型的结构的元数据在哪里?

    没有。对于原始值数据 - 无论是单个值,还是数组/向量/其他,消费代码 都是知道如何解释它的东西。 是什么只是:字节。

    如果没有结构元数据,您如何知道运行时收到的结构以及如何处理/解析它?

    因为它是在 API 中定义的,要么是在签名中,要么是用诸如“指针指向 len 类型 Foo 的元素的开头”之类的人类语言来定义

    您需要将数据嵌入到结构中

    不,你没有;您只需要提前同意您发送/接收的内容。这就是不同代码库之间绝大多数交互的工作方式,并且一直有效。 拥有对象元数据是例外,而不是常态。

    你甚至如何从非托管空间返回课程?

    如果这里所说的“类”是指托管对象,则不会。

    【讨论】:

    • 谢谢 Marc,你能在 Because it is defined in the API, either in a signature 上扩展一下吗?在这种情况下,您在谈论什么 API/签名?例如,我知道用于 C#/.NET 的 IL 在程序集中写入了大量元数据,但是 c/c++ 剥离了所有识别数据并编译为机器代码——如果不是来自结构数据,它会从哪里来?您所说的是 struct 本质上是原始内存字节的序列/数组,并且接收器以某种方式知道如何读取它们。 “如果在这种情况下,“类”是指托管对象。” -- 在原生的 c/c++ 中也存在类
    • @Civ01 “类也存在于 c/c++ 中”,但它的含义有所不同;它不是“类”的可互换共享概念; .NET 中的 RTTI/反射旨在提供更多信息。至于“如果不是来自结构数据,它将来自哪里”:来自首先编译的代码。在 C++ 中,这是非常字面的,它是编译的一部分;假设您不进行 AOT 编译,它在 .NET 中会稍微一点,因为 JIT 加载程序需要参与 IL 和机器代码之间,并且源程序集可能在构建和加载。
    • 主要是,对于 C++ 类型,除非另有说明,否则假定与 Win32 API 兼容的选项。如果你用奇怪的选项编译 C++ 代码,你要么必须使用属性来指定映射,要么它可能不起作用。在极端情况下,您将不得不使用混合模式 C++ 在托管类型和非托管类型之间建立桥梁。C# 不解析 C 头文件,因此,您有责任确保在双方定义的类型都具有完全相同的表示。
    猜你喜欢
    • 2010-12-28
    • 1970-01-01
    • 2011-02-24
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多