首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关键词‘In,out,ref`’vs属性`[In],[Out],[In,Out]‘

关键词‘In,out,ref`’vs属性`[In],[Out],[In,Out]‘
EN

Stack Overflow用户
提问于 2019-05-12 07:53:39
回答 1查看 585关注 0票数 5

我知道第一组关键字in, out, ref可以用于所有C#函数,第二组属性[In], [Out], [In, Out]用于封送器。

当在本机代码的函数声明中使用时,我不确定它们的意思是否相同。例如,以下两个声明是否等效?

代码语言:javascript
复制
[DllImport("xxx.dll")]
void FillArray1(ref int[] arr, in int length);

[DllImport("xxx.dll")]
void FillArray2([In, Out] int[] arr, [In] int length);

是否有任何情况,这两套是不等价的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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参数。除非将InAttributeOutAttribute (或仅OutAttribute)应用于方法参数,否则不会看到对这些类型的更改。

因此,无论指定Out属性,本机侧都会获得正确的指针。在这里指定[Out]是封送处理程序的需要,因此它不会忽略托管内存的复制回会话。

类似地,in int length将传递一个对整数的引用,并且与[In] int length不一样,后者只是通过值传递参数。可以省略[In],因为在本例中这是默认的封送处理行为。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56097222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档