我们什么时候应该使用这个属性,为什么我们需要它?例如,如果c中的本机函数将指向无符号字符的指针作为参数,并且我知道需要它来完成无符号字符的数组,那么为什么我不能使用C#中的字节数组来使用此函数呢?是否有必要进行编组?
发布于 2011-06-16 11:51:24
在大多数情况下,运行库将能够自动确定如何在本机代码和托管代码之间封送数据,因此您通常不需要指定该属性。只有在定义中存在歧义(并且您希望准确地告诉运行时如何编组数据)或者需要非默认行为时,才需要使用MarshalAs。
根据我的经验,只有在处理字符串时才真正需要MarshalAs,因为在本机代码中有太多不同的表示形式: unicode/ansi、c字符串等等。
发布于 2011-06-16 13:28:33
MarshalAs属性的其他用途是使用ByValArray和SizeConst参数封送固定大小的数组(包括固定大小的字符串)。例如,Windows API中的许多结构都包含固定大小的字符串。
发布于 2021-12-09 10:47:12
基于Type marshaling的Microsoft文档
当类型需要在托管代码和本机代码之间交叉时,
封送处理是转换类型的过程。封送处理是必需的,因为托管代码和非托管代码中的类型不同。例如,在托管代码中,您有一个字符串,而在非托管世界中,字符串可以是Unicode (“宽”)、非Unicode、以null结尾的ASCII等。默认情况下,P/Invoke子系统尝试基于本文描述的默认行为执行正确的操作。但是,对于需要额外控制的情况,可以使用MarshalAs属性来指定非托管端的预期类型。
通常,运行时会尝试在封送处理时做“正确的事情”,以减少您的工作量。
从文档到Blittable和Non-Blittable Types的以下link中解释了哪些类型需要特殊处理
大多数数据类型在托管内存和非托管内存中都有共同的表示形式,不需要互操作封送拆收器进行特殊处理。这些类型之所以称为blittable类型,是因为它们在托管代码和非托管代码之间传递时不需要转换。
Non-blittable类型将是您问题的答案。您必须对以下内容进行编组:
数组、布尔值、字符、类、对象、字符串、值类型(结构)、委托、非托管数组,这些数组可以是COM样式的安全数组,也可以是具有固定或可变长度的C样式数组。
非托管结构还可以包含嵌入的数组或布尔值(非blittable类型)。根据doc,你必须小心
从平台调用返回的
结构必须是blittable类型。平台调用不支持将非blittable结构作为返回类型。
https://stackoverflow.com/questions/6366850
复制相似问题