我知道第一组关键字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);
Run Code Online (Sandbox Code Playgroud)
是否存在两个集合不等价的情况?
它们并不等同。
对于 ,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
除非您将andOutAttribute
(或仅OutAttribute
)应用于方法参数,否则您不会看到这些类型的更改。
因此,无论指定属性如何,本机端都会获得正确的指针Out
。[Out]
封送拆收器需要在此处进行指定,这样它就不会忽略到托管内存的回拷会话。
类似地,将传递对整数的引用,并且与仅按值传递参数的in int length
不同。[In] int length
可以[In]
省略,因为这是这种情况下的默认封送行为。
归档时间: |
|
查看次数: |
996 次 |
最近记录: |