I want to define a callback function in my C# code and pass it to some native C++ code, then have the C++ code invoke it later. The callback needs to receive a variable-length array of structs, with each struct containing some array fields.
I have had success passing a single struct with an array field, and a variable-length array of structs with scalar fields, but not a variable-length array of structs with array fields.
Here's my C# code. I'm omitting the code that registers the C# callback method with the C++ code, as I don't think that's the issue; it works fine except for the specific problematic case.
The struct:
[StructLayout(LayoutKind.Sequential)]
public struct Foo
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.R4, SizeConst = 2)]
public float[] a;
}
The callback declaration
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void Callback(Int32 count,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Foo[] foos);
The callback method itself
public void onFoo(Int32 count, Foo[] foos) {
Debug.Log("in onFoo callback, foo values=" + foo[0].a + ", " + foo[1].a);
}
And here's the C++ code:
First the struct:
typedef struct {
float a[2];
} Foo;
and the callback invocation:
Foo* foos = new Foo[2];
foos[0].a[0] = 1.11;
foos[0].a[1] = 2.22;
foos[1].a[0] = 3.33;
foos[1].a[1] = 4.44;
onFoo(2, foos);
delete[] foos;
For the problematic case, my callback method is not being invoked (I get no log output). I've done quite a lot of Googling but haven't found anything covering this particular scenario. Do I need a custom marshaler?
Listcontainer, since lists by definition are variable length?