我想在我的C#代码中定义一个回调函数,并将其传递给一些本机C ++代码,然后让C ++代码稍后调用它。回调需要接收一个可变长度的结构数组,每个结构包含一些数组字段。
我成功传递了一个带有数组字段的结构,一个带有标量字段的可变长度结构数组,但没有带有数组字段的可变长度结构数组。
这是我的C#代码。我省略了用C ++代码注册C#回调方法的代码,因为我不认为这是问题所在。除了特定的问题情况外,它的工作正常。
结构:
[StructLayout(LayoutKind.Sequential)]
public struct Foo
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.R4, SizeConst = 2)]
public float[] a;
}
回调声明
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void Callback(Int32 count,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Foo[] foos);
回调方法本身
public void onFoo(Int32 count, Foo[] foos) {
Debug.Log("in onFoo callback, foo values=" + foo[0].a + ", " + foo[1].a);
}
这里是C ++代码:
首先是结构:
typedef struct {
float a[2];
} Foo;
和回调调用:
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;
对于有问题的情况,我的回调方法没有被调用(我没有得到日志输出)。我做了很多谷歌搜索,但没有发现任何涉及这种特殊情况的内容。我需要一个自定义封送器吗?
答案 0 :(得分:1)
这不是一个答案,而是对你的回调调用的观察。自从我完成C ++以来已经很多年了,但不应该是以下
Foo* foos = new Foo[2];
foos[0].a = 1.11;
foos[1].a = 2.22;
onFoo(2, foos);
要
Foo* foos = new Foo[2];
foos[0].a[0] = 1.11;
foos[0].a[1] = 1.12;
foos[1].a[0] = 2.22;
foos[1].a[1] = 2.23;
onFoo(2, foos);
答案 1 :(得分:0)
好的,在这里用另一种有效的方法回答我自己的问题。如果其他人出现并解决原先陈述的问题,我会不予理会。
解决方法是将一个struct指针数组传递给回调而不是结构数组。回调签名更改为
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void Callback(Int32 count,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] IntPtr[] fooPtrs);
在C ++代码中,我分配了一个Foo *数组,然后分别分配和初始化每个Foo,将其指针存储到数组中。
Foo** foos = new Foo*[2];
Foo* foo1 = new Foo();
foo1->a[0] = 1.11;
foo1->a[1] = 2.22;
foos[0] = foo1;
Foo* foo2 = new Foo();
foo2->a[0] = 3.33;
foo2->a[1] = 4.44;
foos[1] = foo2;
onFoo(2, foos);
delete foo1;
delete foo2;
delete[] foos;
回到C#端,在回调方法中,我分配一个Foo数组,循环传入的IntPtr数组,并使用Marshal.PtrToStructure编组每个元素,如下所示:
public void onFoo(Int32 count, IntPtr[] FooPtrs)
{
Foo[] foos = new Foo[count];
for (int i=0; i< count; i++)
{
foos[i] = (Foo)Marshal.PtrToStructure(ptrs[i], typeof(Foo));
}
}
这种方法的缺点是需要更多的内存分配和复制,而不是能够将C#struct数组直接映射到C ++中分配的内存。