我在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。
答案 0 :(得分:8)
来自documentation,强调:
作为优化,仅包含blittable成员的blittable类型和类的数组将固定而不是在编组期间复制。当呼叫者和被呼叫者在同一个公寓中时,这些类型可以看起来被编组为输入/输出参数。但是,这些类型实际上是作为In参数封送的,如果要将参数封送为In / Out参数,则必须应用InAttribute和OutAttribute属性。
由于byte
是blittable,因此您的字节数组被固定而不是复制,因此编组为In / Out。
当我用char []替换byte []时,CLR将遵循我的In-Out属性。
C#类型char
是not blittable。 char
数组未固定,因此[In] char[]
编组为In参数。