MarshalAs属性案例研究

本文关键字:案例 属性 MarshalAs | 更新日期: 2023-09-27 17:59:11

我们应该在什么时候使用这个属性,为什么需要它?例如,如果c中的本机函数将指向无符号字符的指针作为参数,并且我知道需要它来实现无符号字符数组,为什么我不能使用c#中的字节数组来使用此函数?有必要进行编组吗?

MarshalAs属性案例研究

在大多数情况下,运行时将能够自动确定如何在本机代码和托管代码之间封送数据,因此通常不需要指定属性。只有当定义中存在歧义时(并且您希望告诉运行时如何精确地封送数据),或者如果您需要非默认行为,MarshalAs才是必要的。

根据我的经验,只有在处理字符串时才真正需要MarshalAs,因为在本机代码中有很多不同的表示;unicode/ansi、c字符串与否等。

MarshalAs属性的其他用途是使用ByValArray和SizeConst参数编组固定大小的数组(包括固定大小的字符串)。例如,Windows API中的许多结构都包含固定大小的字符串。

基于类型封送的Microsoft文档

封送是当类型需要在托管代码和本机代码之间交叉时转换类型的过程。需要编组,因为托管代码和非托管代码中的类型不同。在托管中例如,代码中有一个String,而在非托管世界中字符串可以是Unicode("宽")、非Unicode、以null结尾、ASCII、,等等。默认情况下,P/Invoke子系统会尝试做正确的事情基于本文中描述的默认行为。然而,对于在需要额外控制的情况下,可以使用MarshalAs属性,以指定非托管端。

通常,运行时尝试执行";正确的事情;封送时要求你做最少的工作。

哪些类型需要特殊处理,请参见从文档到可起泡和不可起泡类型的以下链接:

大多数数据类型在托管和非托管内存,不需要interop进行特殊处理执法官。这些类型被称为blitable类型,因为它们没有在托管代码和非托管代码之间传递时需要转换。

非blitable类型将是您问题的答案。您必须为以下内容进行编组:

数组、布尔值、char、类、对象、字符串、值类型(结构)、委托、非托管数组,这些数组是COM样式的安全数组或具有固定或可变长度的C样式数组。

非托管结构也可以包含嵌入式数组或布尔值(非blitable类型)。根据文件,你必须小心:

从平台调用返回的结构必须是blitable类型。平台调用不支持非blitable结构作为返回类型。