Marshaling a pointer to an array of types (managed C# -> unmanaged C++)
Question
I am having some trouble settling on a way to represent a structure that contains a pointer to an array of shorts in my managed code. The struct looks like this:
typedef struct
{
short size;
unsigned short** shortValues;
} UnmanagedStruct;
memory for 'shortValues
' is allocated inside unmanaged code -- therefore even though that field is simply a pointer to an array of short values, an additional level of indirection was added so that allocated memory is seen by the caller (managed code) too. The 'size
' field represents the number of elements in the array. How do I represent this in managed code?
I thought I'd pass it in just an IntPtr
, then I couldn't figure out how to access the values once the unmanaged call returns.
Solution
Is unsafe code ok?
public unsafe struct UnmanagedStruct
{
public short size;
public ushort** shortValues;
}
[DllImport("example.dll")]
public static extern void GetUnmanagedStruct(out UnmanagedStruct s);
If you have a pointer to an array of ushort
s:
public static unsafe void WriteValues()
{
UnmanagedStruct s;
GetUnmanagedStruct(out s);
for (var i = 0; i < s.size; i++)
{
ushort x = (*s.shortValues)[i];
Console.WriteLine(x);
}
}
If you have an array of null-terminated arrays of ushort
s:
public static unsafe void WriteValues()
{
UnmanagedStruct s;
GetUnmanagedStruct(out s);
for (var i = 0; i < s.size; i++)
{
for (ushort* p = s.shortValues[i]; p != null; p++)
{
ushort x = *p;
Console.WriteLine(x);
}
}
}