当前位置: 首页 > 编程语言 > C#

编组.NET通用类型分享

时间:2023-04-10 22:43:59 C#

使用System.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential)]classAClass{}[StructLayout(LayoutKind.Sequential)]structAStruct{}[StructLayout(LayoutKind.Sequential)]classB{AClass值;}[StructLayout(LayoutKind.Sequential)]类C{T值;}classProgram{staticvoidM(objecto){Console.WriteLine(Marshal.SizeOf(o));}staticvoidMain(){M(newAClass());M(新结构体());M(新B());M(新C());M(新C());对M()的前四次调用成功,但在最后一次调用时,SizeOf抛出ArgumentException:“Type'C`1[AClass]'不能作为非托管结构进行封送;无法计算有意义的大小或偏移量。“为什么?具体来说,为什么SizeOf阻塞在C上,而不是B或C上?编辑:因为它在评论中被问到,这是一个“现实世界”的问题,它激发了这个主要是学术性的问题:我正在调用一个CAPI,它基本上是一个C函数,它操纵(指向)许多不同类型的简单C结构。都包含一个共同的头部,后面跟着一个字段,但该字段的类型在不同的结构中是不同的。标头中的标志指示字段的类型。(很奇怪,是的,但这就是我必须处理的)。如果我可以定义一个泛型类型C和一个C#外部声明M(C),然后在一行中调用M(C)并在另一行中调用M(C),那么我就有了一个简短而有效的互操作解决方案。但是考虑到JaredPar的回答,我似乎必须为每个结构创建一个单独的C#类型(尽管继承可以提供一个公共标头)。任何互操作性方案都不支持泛型作为规则。如果您尝试封送泛型类型或值,P/Invoke和COMInterop都将失败。所以我认为Marshal.SizeOf在这种情况下未经测试或不受支持,因为它是特定于marshal的函数。聚合对象T的大小是未知的(如果T是引用类型,它将是指针的大小,如果它是值类型,它将主要是任何值)。我认为您可以通过在字段“值”上设置MarshalAs属性来指定最接近的匹配类型(例如,Unmanagedtype.SysInt)来解决这个问题。请注意,它仍然不适用于所谓的不可映射类型(即无法轻易推断出其字段偏移量和大小的类型)。但是AFAIK,不推荐在互操作中使用泛型。以上就是《C#学习教程:Marshalling.NETgenerics》的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: