元帅的[In] [Out]属性

时间:2015-06-06 07:29:43

标签: c# pinvoke marshalling dllimport

我在C#代码中调用了一个非托管函数。

此功能的声明如下:

int myFun(unsigned char* inputBuffer, unsigned char* &outputBuffer);

我使用此功能如下:

[DllImport("myDLL.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int myFun([In] byte[] inputBuffer, out IntPtr outputBuffer);

byte[] a = Encoding.ASCII.GetBytes("sampletext!");
IntPtr b;
res = myFun(a, out b);

虽然我提到了[InAttribute]的{​​{1}},但该功能仍然更改了byte[] inputBuffer的值。似乎CLR正在使用其自己的默认编组行为。 我使用了a,因为它是byte[]的C#等价物。

当我用unsigned char*替换byte[]时,CLR将遵循我的输入输出属性。

我非常感谢你的帮助。 有关详细信息,请阅读此msdn page

1 个答案:

答案 0 :(得分:8)

来自documentation,强调:

  

作为优化,仅包含blittable成员的blittable类型和类的数组将固定而不是在编组期间复制。当呼叫者和被呼叫者在同一个公寓中时,这些类型可以看起来被编组为输入/输出参数。但是,这些类型实际上是作为In参数封送的,如果要将参数封送为In / Out参数,则必须应用InAttribute和OutAttribute属性。

由于byte是blittable,因此您的字节数组被固定而不是复制,因此编组为In / Out。

  

当我用char []替换byte []时,CLR将遵循我的In-Out属性。

C#类型charnot blittablechar数组未固定,因此[In] char[]编组为In参数。