How can I pass a pointer to an array using p/invoke in C#?

后端 未结 3 672
轻奢々
轻奢々 2020-11-30 06:32

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 ch         


        
相关标签:
3条回答
  • 2020-11-30 07:13

    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.

    0 讨论(0)
  • 2020-11-30 07:23

    Here is the appropriate signature for the native function.

    [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="Func")]
    public static extern  void Func(System.IntPtr bytes) ;
    
    0 讨论(0)
  • 2020-11-30 07:28

    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);
    
    0 讨论(0)
提交回复
热议问题