Xamarin Unified API - 如何使用IntPtr处理数组绑定?

时间:2015-03-25 15:09:31

标签: ios binding xamarin.ios xamarin accelerate-framework

我在Xamarin.iOS中长时间使用我的绑定和静态加速Obj C库。由于统一的API和较新iOS设备中的64位arch,我被迫成功更新和编译我的新版本库并将其与适当的绑定链接。

为了实现良好的性能并且由于处理大块数据(大图像阵列)而导致数据传输obj-C&#C#之间没有时间损失我决定使用不安全的代码将数组从c#绑定到obj-c并且通常使用IntPtr包装数组,即:

private IntPtr WrapIntArray(int[] array) {
    IntPtr intPtr;
    unsafe
    {
        fixed (int* pArray = array)
        {
            intPtr = new IntPtr((void *) pArray);
        }
    }
    return intPtr;
}

然后将此IntPtr传递给导出的绑定方法:

[Export("....")]
void method(IntPtr input, IntPtr output);

如果在32位单音素上运行,我的库在armv7设备上运行良好。

当我今天决定在armv7 + arm64的构建配置中运行时,我的库停止工作并且我发生了崩溃。在调查和调试之后,我发现现在当我在C#中为数组声明我的IntPtr包装器时它的大小为8字节(64位)。

因为我使用obj-c库来设置"输出"通过为数组分配32位值(即输出[43] = 2)的方法导致崩溃。

有人可以帮助我了解我如何处理这个新案例的方式我的绑定方式,而不更改我的obj-c库?

由于

安东尼奥

1 个答案:

答案 0 :(得分:1)

上面示例的最大问题是您获取了数组的地址,并且只保证地址在“fixed”语句的持续时间内保持固定。一旦你离开它,GC可能会移动数据。

现在,由于这些是图像,因此可能很大,GC可能不会移动您的数据,但这是GC的启发式问题。最好避免这种做法。

您的方法声明中的IntPtrs应该在C中显示为“void *”或类似的东西。所以这真的取决于你在C方面做了什么。