Передача многомерного массива из управляемого кода в неуправляемый код - PullRequest
8 голосов
/ 23 августа 2011

Я хотел бы сделать следующее:

  1. Создать три dimesinal массива в коде c # следующим образом:

    var myArray = new short[x,y,z];
    UnanagedFunction(myArray);
    
  2. Передать егок неуправляемому коду (c ++), например так:

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

ОБНОВЛЕНО Когда я пытаюсь выполнить следующий код, у меня возникает ошибка времени выполнения:

Попытка чтения или записи в защищенную память.

Спасибо !!!

Ответы [ 2 ]

7 голосов
/ 25 августа 2011
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 ++ функция, позволяющая принимать размеры массива, иначе вы сможете использовать только трехмерные массивы определенного размера

2 голосов
/ 25 августа 2011

Я пишу это на чистом C #, но если вы уберете unsafe static из Func, 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
}
...