Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Marshal's [In] [Out] Attributes

I'm invoking an unmanaged function in my C# code.

The declaration of this function is as follow:

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

I use this function as follow:

[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);

Although I mentioned [InAttribute] for byte[] inputBuffer, the function still changeds the values of a. It seems that CLR is using its own default marshaling behavior. I used byte[] because it is C# equivalent for unsigned char*.

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

I highly appreciate your help. For more information please read this msdn page.

like image 806
Yasser Mohseni Avatar asked Jun 06 '15 07:06

Yasser Mohseni


People also ask

What is marshalling and why do we need it?

Marshalling is the process of transforming the memory representation of an object into another format, which is suitable for storage or transmission to other software applications. Marshalling allows communication between remote objects by converting an object into serialized form.

What is Marshal class in C#?

Marshaling is the process of creating a bridge between managed code and unmanaged code; it is the homer that carries messages from the managed to the unmanaged environment and reverse. It is one of the core services offered by the CLR (Common Language Runtime.)


1 Answers

From the documentation, with my emphasis:

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.

Since byte is blittable, your array of byte is pinned rather than copied, and so marshals as In/Out.

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

The C# type char is not blittable. An array of char is not pinned, and so [In] char[] marshals as an In parameter.

like image 57
David Heffernan Avatar answered Oct 11 '22 08:10

David Heffernan