问题描述
我想知道 C# 7.3's Unmanaged type constraint 是否提供语言支持来强制类型是 blittable。根据 Blittable and Non-Blittable types 正确进行平台调用需要断言返回类型是 blittable:
从平台调用返回的结构必须是 blittable 类型。平台调用不支持非 blittable 结构作为返回类型。
然而,官方文档似乎没有说明 C# 强制 unmanaged
类型是“blittable”的任何地方。我对这样假设感到担忧,因为有证据表明,至少在某一时刻,一种类型是否“blittable”只能凭经验来确定。
非托管类型约束文档
The C# 7.3 "Unmanaged type constraint" proposal 包括以下内容:
非托管约束功能将强制执行 C# 语言规范中称为“非托管类型”的类型类。 ...
...
Blittable 与非托管
F# 语言有一个非常相似的特性,它使用关键字 unmanaged。 blittable 名称来自 Midori 中的使用。可能希望在此处查看优先级并改用非托管。
解决语言决定使用非托管
...
这里的短语“非托管类型”似乎指的是 Unsafe code - Pointer Types of the draft C# 6 specification 中定义的“unmanaged_type”(我在 the C# 5 ECMA standard 中没有找到类似的引用)。 unmanaged_type 定义如下:
非托管类型是任何类型,它不是 reference_type 或构造类型,并且不包含任何嵌套级别的 reference_type 或构造类型字段。换句话说,unmanaged_type 是以下之一:
-
sbyte
、byte
、short
、ushort
、int
、uint
、long
、ulong
、char
、float
、double
、decimal
或bool
。 - 任何enum_type。
- 任何pointer_type。
- 任何用户定义的 struct_type 不是构造类型并且仅包含 unmanaged_types 字段。
我还没有发现interop marshaling documentation中提到的C# 7.3的unmanaged
类型约束;该文档似乎早于该功能。
Blittable 类型文档
Blittable and Non-blittable Types 声明以下内容是可 blittable 的:
-
System.Byte
、System.SByte
、System.Int16
、System.UInt16
、System.Int32
、System.UInt32
、System.Int64
、System.UInt64
、System.IntPtr
、System.UIntPtr
、System.Single
、System.Double
- blittable 类型的一维数组,例如整数数组。但是,包含 blittable 类型的可变数组的类型本身不是 blittable。
- 仅包含 blittable 类型的格式化值类型(如果它们被封送为格式化类型,则还包含类)。有关格式化值类型的详细信息,请参阅值类型的默认封送处理。
是否每个 unmanaged
类型都是“Blittable”?
起初我认为上面的定义意味着每个 unmanaged
类型都是“blittable”的。但我还没有找到任何直接出现并说明这一点的官方文件。在实现 unmanaged
类型约束功能之前,我发现的最接近的是 this reply(据我了解时间线):
这与互操作封送处理中的 Blittable 类型有什么关系?相同?或相似但略有不同?
是一样的。
这似乎是肯定的证据,但它也是作为设计决策基础的相当薄弱的证据。 (FWIW,这种交换也可以解释为所有“blittable”类型都是 unmanaged
,这似乎不太可能是真的。)
然后,根据文档,bool
不是“blittable”,System.Boolean
是 unmanaged
。那种复杂性is acknowledged but not directly addressed for the interop marshaler in the original proposal.
为什么我对此感到担忧
我不是一个活跃的 C# 开发人员,而这的历史似乎已经展开,而且肯定有我错过的线索。在我发现的线索中,很多都是否定的。似乎有一段时间 P/Invoke 的实现抵制了区分 blittable 和非 blittable 类型的总内涵定义。换句话说,至少在某些 C# 版本中,先验确认互操作封送拆收器是否认为一个类型是 blittable 是非常重要的(或者可能不可能)。或者至少看起来是这样。例如,Hans Passant wrote in 2015
没有简单的方法可以确定一个类型是否是 blittable,除了它不能正常工作或使用调试器和比较指针值。
另一个线索是 The fastest way to check if a type is blittable?(2012 年提出的问题)中的每个答案的方法似乎都是经验性的。这似乎是进一步否定的证据。
我想可能是所有 unmanaged
类型都是“blittable”,但并非所有“blittable”类型都是 unmanaged
。但这只是我的猜测。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)