Search code examples
pinvoke

How to pass variable length structure to pinvoke C function in C#


My C structure format is this:

typedef struct pt_data {
  int Length;   ///< Length of the Data field in bytes
  uchar Data[1];    ///< The data itself, variable length
} PT_DATA;

My C function is this:

PT_STATUS PTSetFingerData (
IN PT_CONNECTION hConnection,
IN PT_LONG lSlotNr,
IN PT_DATA *pFingerData
)

Now I want to put a wrapper for this function in C#.

How can I do this? In particular, how can I do this for passing the C# PT_DATA struct to PT_DATA C struct?


Solution

  • You need to marshal the data manually. A variable length struct cannot be marshalled by the p/invoke marshaller.

    In your case the obvious way to do this would be to declare the PTDATA* argument as byte[] in your p/invoke. Then you just need to populated the byte array before calling the function. The first 4 bytes are the length of the subsequent data.

    static byte[] GetPTData(byte[] arr)
    {
        byte[] len = BitConverter.GetBytes(arr.Length);
        byte[] data = new byte[sizeof(int) + arr.Length];
        Array.Copy(len, data, sizeof(int));
        Array.Copy(arr, 0, data, sizeof(int), arr.Length);
        return data;
    }