C# 关键词'in,out,ref`vs属性'[in],[out],[in,out]`
我知道第一组关键字C# 关键词'in,out,ref`vs属性'[in],[out],[in,out]`,c#,marshalling,C#,Marshalling,我知道第一组关键字in,out,ref可用于所有C#函数,第二组属性[in],[out],[in,out]用于marshaller 我不确定它们在本机代码的函数声明中使用时是否表示相同的意思。例如,以下两个声明是否等效 [DllImport("xxx.dll")] void FillArray1(ref int[] arr, in int length); [DllImport("xxx.dll")] void FillArray2([In, Out] int[] arr, [In] int
in,out,ref
可用于所有C#函数,第二组属性[in],[out],[in,out]
用于marshaller
我不确定它们在本机代码的函数声明中使用时是否表示相同的意思。例如,以下两个声明是否等效
[DllImport("xxx.dll")]
void FillArray1(ref int[] arr, in int length);
[DllImport("xxx.dll")]
void FillArray2([In, Out] int[] arr, [In] int length);
是否存在两组不相等的情况?它们不相等
[DllImport("xxx.dll")]
void FillArray1(ref int[] arr, in int length);
[DllImport("xxx.dll")]
void FillArray2([In, Out] int[] arr, [In] int length);
对于ref int[]arr
将自动应用默认的[In,Out]
属性,但它仍然与[In,Out]int[]arr
不同
ref int[]arr
是双间接寻址(通过引用传递的引用类型)。如果本机端定义如下:int32\u t**arr
,请使用此选项。这样不仅可以替换元素,还可以替换整个数组实例
另一方面,[In,Out]int[]arr
是一个通过值传递的简单引用。如果本机端也使用单个间接寻址,例如int32\u t*arr
,则使用此选项。通常在C#中,如果按值传递数组(这是一种引用类型),则被调用的方法可以替换元素,这些元素将从调用方反映出来。但是,P/Invoke封送处理有点有效:
默认情况下,由于性能原因,按值传递的引用类型(类、数组、字符串和接口)在参数中被封送为。除非将InAttribute
和OutAttribute
(或仅OutAttribute
)应用于方法参数,否则不会看到对这些类型的更改
因此,无论指定Out
属性如何,本机端都会获得正确的指针。封送拆收器需要在此处指定[Out]
,以便不会忽略到托管内存的复制回会话
类似地,in int length
将传递对整数的引用,这与[in]int length
不同,后者仅通过值传递参数。[In]
可以省略,因为在这种情况下这是默认的封送处理行为。我不确定In
或Out
属性做什么,但是关键字In
和Out
在编译时被检查(对于只读/只读访问),并且参数作为引用而不是值传递。通常,可以在运行时通过反射查询属性