修复了带锯齿数组的语句

我有锯齿状的数组,我需要传递给外部方法。

[DllImport(...)] private static extern int NativeMethod(IntPtr[] ptrArray); ... fixed (ulong* ptr = array[0]) { for (int i = 0; i < array.Length; i++) { fixed (ulong* p = &array[i][0]) { ptrArray[i] = new IntPtr(p); } } NativeMethod(ptrArray); } 

问题是ptr未使用,因编译而被删除。 根据它的固定声明也被删除。 所以数组被GC移动,使得ptrArray元素变为无效。

将锯齿状数组作为指向本机方法的指针的一维数组传递的最佳方法是什么?

更新:

这是NativeMethod的C ++代码:

 NativeClass::NativeMethod(const int* array) 

你的问题在于你需要修复数组,因为那是你正在使用的数组。 你可以固定数组,以便GC不收集它:

  GCHandle h = GCHandle.Alloc(array, GCHandleType.Pinned); 

UPDATE

正如您正确指出的那样,数组中的每个数组也需要固定。

我已经能够通过外部Pinvoke方法将C#锯齿状数组传递给C ++,而不使用不安全的C#代码,如下面的代码示例所示。 但我仍然担心在非调试模式下GC会引起副作用。 这是测试代码(在调试模式下工作):

 [Test, Ignore] public void Test_JaggedArrayPInvoke() { var jaggedArray = new int[3][]; jaggedArray[0] = new int[1] { 9 }; jaggedArray[1] = new int[4] { 1, 2, 3, 8 }; jaggedArray[2] = new int[2] { 1, 2 }; //GCHandle mainHandle = GCHandle.Alloc(jaggedArray, GCHandleType.Pinned); //This does not work var pinnedHandles = new GCHandle[3]; var jaggedArrayPtrs = new IntPtr[3]; for (int i = 0; i < 3; i++) { pinnedHandles[i] = GCHandle.Alloc(jaggedArray[i], GCHandleType.Pinned); jaggedArrayPtrs[i] = pinnedHandles[i].AddrOfPinnedObject(); } var result = JaggedArrayPInvoke_TEST(jaggedArrayPtrs); Console.WriteLine(result); //returns 8 as it should. //mainHandle.Free(); for (int i = 0; i < 3; i++) { pinnedHandles[i].Free(); } } //The C++ test method: extern "C" __declspec(dllexport) int __stdcall JaggedArrayPInvoke_TEST(int** jaggedArray); __declspec(dllexport) int __stdcall JaggedArrayPInvoke_TEST(int** jaggedArray) { return jaggedArray[1][3]; } 

如果我要取消注释mainHandle部分,我得到一个参数exception“对象包含非原始或非blittable数据”。 那么有可能固定jaggedArray并且真的需要它吗? (我模糊地回想一下,如果不再使用GC,处于发布模式的GC可能会重新收集方法中的内存。)我认为,将jaggedArray转换为类字段变量可以使其从GC角度安全。