使用[In,Out]和将参数从C#传递给C++时只使用ref有什么区别吗?
我发现了几个不同的SO帖子,以及来自MSDN的一些东西也接近我的问题,但并没有完全回答它.我的猜测是我可以安全地使用ref,就像我使用[In,Out]一样,并且marshaller将不会采取任何不同的行为.我担心的是它会采取不同的行为,并且C++对我传递的C#结构不满意.我已经在我正在使用的代码库中看到了两件事情......
以下是我发现并一直在阅读的帖子:
P/Invoke [In,Out]属性是否可选用于编组数组? 让我觉得我应该使用[In,Out].
这三个帖子让我觉得我应该使用[In,Out],但我可以使用ref代替它,它将具有相同的机器代码.这让我觉得我错了 - 所以问这里.
Han*_*ant 22
的使用ref或者out是不随意的.如果本机代码需要传递引用(指针),那么如果参数类型是值类型,则必须使用这些关键字.这样抖动就知道要生成一个指向该值的指针.你必须忽略他们,如果该参数类型是引用类型(类),对象已经引擎盖下指针.
然后需要[In]和[Out]属性来解决指针的歧义,它们不指定数据流.[in]总是由pinvoke marshaller暗示,因此不必明确说明.但是,如果您希望在代码中看到本机代码对结构或类成员所做的任何更改,则必须使用[Out].pinvoke marshaller避免自动复制以避免费用.
那么进一步的怪癖是[Out]通常不是必需的.当值为blittable时发生,这是一个昂贵的单词,表示托管值或对象布局与本机布局相同.然后,pinvoke marshaller可以获取快捷方式,固定对象并将指针传递给托管对象存储.由于本机代码直接修改托管对象,因此您将不可避免地看到更改.
你一般都非常想要追求的东西,它非常有效.通过给出[StructLayout(LayoutKind.Sequential)]属性的类型,它可以帮助CLR用来重新排列字段以获得最小对象的优化.并且只使用简单值类型或固定大小缓冲区的字段,尽管您通常不会选择这些字段.永远不要使用bool,而是使用byte.除了不能正常工作或使用调试器和比较指针值之外,没有简单的方法可以确定类型是否是blittable.
只需要明确,并在需要时始终使用[Out].如果事实证明没有必要,它不会花费任何成本.它是自我记录的.如果本机代码的体系结构发生变化,您仍然可以感觉良好.
| 归档时间: |
|
| 查看次数: |
4876 次 |
| 最近记录: |