我知道第一组关键字in, out, ref可以用于所有C#函数,第二组属性[In], [Out], [In, Out]用于封送器。
当在本机代码的函数声明中使用时,我不确定它们的意思是否相同。例如,以下两个声明是否等效?
[DllImport("xxx.dll")]
void FillArray1(ref int[] arr, in int length);
[DllImport("xxx.dll")]
void FillArray2([In, Out] int[] arr, [In] int length);是否有任何情况,这两套是不等价的?
发布于 2019-05-12 11:41:10
它们是不对等的。
对于ref int[] arr,默认的[In, Out]属性将自动应用,但它仍然与[In, Out] int[] arr不一样。
ref int[] arr是一个双间接(通过引用传递的引用类型)。如果定义了本机端,就使用它:int32_t** arr。这样不仅可以替换元素,还可以替换整个数组实例。
另一方面,[In, Out] int[] arr是一个通过值传递的简单引用。如果本地方也使用单个间接方向,则使用此方法。int32_t* arr。通常在C#中,如果您按值传递数组(这是一个引用类型),则被调用的方法可以替换元素,这些元素将从调用方反映出来。但是,P/Invoke封送处理工作有点不同的。
默认情况下,由于性能原因,通过值传递的引用类型(类、数组、字符串和接口)被封送为
In参数。除非将InAttribute和OutAttribute(或仅OutAttribute)应用于方法参数,否则不会看到对这些类型的更改。
因此,无论指定Out属性,本机侧都会获得正确的指针。在这里指定[Out]是封送处理程序的需要,因此它不会忽略托管内存的复制回会话。
类似地,in int length将传递一个对整数的引用,并且与[In] int length不一样,后者只是通过值传递参数。可以省略[In],因为在本例中这是默认的封送处理行为。
https://stackoverflow.com/questions/56097222
复制相似问题