Search code examples
c#pinvoke

Equivalent for unsigned char * in c#


Possible Duplicate:
unsigned char ** equivalent in c# and have to write the return value in a file

I have to call a win32 dll function

int func1(int arg1, unsigned char *arg2, int *arg3);

and i wrote wrapped c# as

public extern int fuc1(int arg1, out IntPtr arg2, out IntPtr arg3);

The arg2 has to allocate 2048 bytes and send it to the win32 dll. I'll get arg2 and arg3 as output.

how can i declare in c# test application as well as c# wrapper. am i doing it right ?


Solution

  • byte in C# is unsigned 8-bit int. byte[] is an array of them. To get a pointer to this array, use:

     var myArray = new byte[2048];
     fixed(byte* arg2 = myArray)
     {
          // use arg2
     }
    

    or:

     var myArray = new byte[2048];
     GCHandle pinnedRawData = GCHandle.Alloc(myArray, GCHandleType.Pinned);
     try
     {  
        // Get the address of the data array
        IntPtr pinnedRawDataPtr = pinnedRawData.AddrOfPinnedObject();
     }
     finally
     {
        // must explicitly release
        pinnedRawData.Free(); 
     } 
    

    Alternatively, if the called function will not cache a pointer to the array, you can simply do this:

     public static extern int fuc1(int arg1, [In,Out] byte[] arg2, ref int arg3);
    
     var arg1 = 0;
     var arg2 = new byte[2048];
     int arg3 = 42; // If this value won't be used, you can skip initializing arg3 and mark arg3 as out instead of ref (of course, this is pedantic and extraneous, and C# shouldn't even have 'out' as a keyword)
    
     func1(arg1, arg2, ref arg3);
    

    P/Invoke will pin it automatically.

    MSDN Marshaling Arrays of Types

    Related SO question