将托管代码中的多维数组传递给非托管代码

我想做以下事情:

  1. 在c#代码中创建三个像素数组,如下所示:

    var myArray = new short[x,y,z]; UnanagedFunction(myArray); 
  2. 将它传递给非托管代码(c ++),如下所示:

     void UnmanagedFunction(short*** myArray) { short first = myArray[0][0][0]; } 

更新当我尝试以下代码时,我遇到运行时错误:

尝试读取或写入受保护的内存。

谢谢!!!

 IntPtr Array3DToIntPtr(short[, ,] Val) { IntPtr ret = Marshal.AllocHGlobal((Val.GetLength(0) + Val.GetLength(1) + Val.GetLength(2)) * sizeof(short)); int offset = 0; for (int i = 0; i < Val.GetLength(0); i++) { for (int j = 0; j < Val.GetLength(1); j++) { for (int k = 0; k < Val.GetLength(2); k++) { Marshal.WriteInt16(ret,offset, Val[i, j, k]); offset += sizeof(short); } } } return ret; } 

这已经过测试并且它可以工作,唯一的限制是当你完成它时你必须在数组指针上调用Marshal.FreeHGlobal ,否则你会得到内存泄漏,我还建议你改变你的c ++函数,这样它接受数组维度,或者您只能使用特定大小的3d数组

我用纯C#编写它,但如果你从Func unsafe static ,那么Func应该在C / C ++中工作。 请注意,我注意到确定可以写这个:-)我正在使用这个索引到C#中任意等级的数组

 static unsafe void Main(string[] args) { var myArray = new short[5, 10, 20]; short z = 0; for (int i = 0; i < myArray.GetLength(0); i++) { for (int j = 0; j < myArray.GetLength(1); j++) { for (int k = 0; k < myArray.GetLength(2); k++) { myArray[i, j, k] = z; z++; } } } // myArray[1, 2, 3] == 243 fixed (short* ptr = myArray) { Func(ptr, myArray.GetLength(0), myArray.GetLength(1), myArray.GetLength(2)); } } // To convert to C/C++ take away the static unsafe static unsafe void Func(short* myArray, int size1, int size2, int size3) { int x = 1, y = 2, z = 3; int el = myArray[x * size2 * size3 + y * size3 + z]; // el == 243 }