23

Example C API signature:

void Func(unsigned char* bytes);

In C, when I want to pass a pointer to an array, I can do:

unsigned char* bytes = new unsigned char[1000];
Func(bytes); // call

How do I translate the above API to P/Invoke such that I can pass a pointer to C# byte array?

3 Answers 3

35

The easiest way to pass an array of bytes is to declare the parameter in your import statement as a byte array.

[DllImport EntryPoint="func" CharSet=CharSet.Auto, SetLastError=true]
public extern static void Func(byte[]);

byte[] ar = new byte[1000];
Func(ar);

You should also be able to declare the parameter as an IntPtr and Marshal the data manually.

[DllImport EntryPoint="func" CharSet=CharSet.Auto, SetLastError=true]
public extern static void Func(IntPtr p);

byte[] ar = new byte[1000];
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(byte)) * ar.Length);
Marshal.Copy(ar, 0, p, ar.Length);
Func(p);
Marshal.FreeHGlobal(p);
Sign up to request clarification or add additional context in comments.

3 Comments

why would the first approach work, and the second not work. This is what i'm facing on a windows phone app.
I know this post is a little old but Marshal.SizeOf(object) does not work with arrays. I am pretty sure you will get an exception if you pass it an array but I do not have VS open in front of me right now to try. To correctly determine the size of an array, for your example the code would be Marshal.SizeOf(typeof(byte)) * ar.Length.
Yes, you're right 9ee1. Marshal.SizeOf can be used for a structure but not an array. I've updated the example code accordingly. Thanks.
8

You can use unsafe code:

unsafe 
{
     fixed(byte* pByte = byteArray)
     IntPtr intPtr = new IntPtr((void *) pByte);
     Func(intPtr);
}

If you need to use safe code, you can use a few tricks:

IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(byteArray));
Marshal.Copy(byteArray, 0, intPtr, Marshal.SizeOf(byteArray));

Func(intPtr);

Marshal.FreeHGlobal(intPtr);

However, the safe code is going to be slow IMHO.

Comments

4

Here is the appropriate signature for the native function.

[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="Func")]
public static extern  void Func(System.IntPtr bytes) ;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.