元帅的 [In] [Out] 属性

Marshal's [In] [Out] Attributes

我在我的 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);

虽然我为byte[] inputBuffer提到了[InAttribute],函数仍然改变了a的值。似乎 CLR 正在使用它自己的默认封送处理行为。 我使用 byte[] 因为它是 unsigned char*.

的 C# 等价物

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

非常感谢您的帮助。 欲了解更多信息,请阅读此 msdn page.

来自documentation,我强调:

As an optimization, arrays of blittable types and classes that contain only blittable members are pinned instead of copied during marshaling. These types can appear to be marshaled as In/Out parameters when the caller and callee are in the same apartment. However, these types are actually marshaled as In parameters, and you must apply the InAttribute and OutAttribute attributes if you want to marshal the argument as an In/Out parameter.

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

When I substitute byte[] with char[] the CLR will follow my In-Out attributes.

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