从托管代码传递多维数组到非托管代码

8

我希望做以下事情:

  1. Create three dimesinal array in c# code like this:

    var myArray = new short[x,y,z];
    UnanagedFunction(myArray);
    
  2. Pass it to unmanaged code (c++) like this:

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

已更新 当我尝试运行以下代码时,出现了运行时错误:

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

谢谢!!!


你不能在C++中这样编写代码。 - Hans Passant
代码的第一部分是C#,第二部分是C++,我现在已经尝试了它,编译器允许我使用C++代码。 - Sergey Kucher
1
也许你可以将你的代码改成一个三元组数组。 - Simon
1
@Simon,一个三元组数组有什么用处呢?你是指四元组(x,y,z和值)吗? - svick
1
你甚至不能在纯C++中完成这个操作。你必须在函数原型中写出除了一个维度以外的所有维度。阅读这篇文章:http://c-faq.com/~scs/cclass/int/sx9a.html (例如,void UnmanagedFunction(short myArray[][10][10])) - xanatos
显示剩余2条评论
2个回答

8
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数组。


2

我正在使用纯C#编写代码,但是如果从Func中删除unsafe staticFunc应该可以在C/C++中工作。请注意,我不确定这样写是否合适。

我正在使用Indexing into arrays of arbitrary rank in 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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接