我一直在 Xamarin.iOS 中使用我的绑定(bind)和静态 Accelerate Obj C 库。由于新 iOS 设备中的统一 API 和 64 位架构,我被迫成功更新和编译我的新版本库并将其与适当的绑定(bind)链接。
为了在数据传输 obj-C<->C# 之间实现良好的性能和不损失时间,因为要处理大块数据(大图像数组),我决定使用不安全代码将数组从 c# 绑定(bind)到 obj-c,并且通常使用 IntPtr 包装数组,即:
private IntPtr WrapIntArray(int[] array) {
IntPtr intPtr;
unsafe
{
fixed (int* pArray = array)
{
intPtr = new IntPtr((void *) pArray);
}
}
return intPtr;
}
然后使用此 IntPtr 传递给导出的绑定(bind)方法:
[Export("....")]
void method(IntPtr input, IntPtr output);
如果在 monotouch 32 位上运行,我的库在 armv7 设备上运行良好。
当我今天决定在 armv7+arm64 的构建配置中运行时,我的库停止工作并且我崩溃了。在调查和调试之后,我发现现在当我在 C# 中为数组声明我的 IntPtr 包装器时,它的大小为 8 字节(64 位)。
因为我使用 obj-c 库通过将 32 位的值分配给数组(即 output[43] = 2)来设置方法的“输出”导致崩溃。
有人可以帮助我了解如何在不更改 obj-c 库的情况下以绑定(bind)的方式处理这个新案例吗?
谢谢
安东尼奥
最佳答案
上面示例的最大问题是您获得了数组的地址,并且该地址只能保证在“固定”语句期间保持固定。一旦您离开它,GC 可能会移动数据。
现在,由于这些是图像,因此可能很大,GC 可能不会移动您的数据,但这是 GC 的启发式问题。最好避免这种做法。
方法声明中的 IntPtr 在 C 中应显示为“void *”或类似的东西。所以这真的取决于你在 C 端做什么。
关于ios - Xamarin 统一 API - 如何使用 IntPtr 处理数组绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29259443/