Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Как передавать массивы из C# в C++(dll)


Автор: kiler4747 15.6.2011, 18:41
Как передать массив из C# в C++(dll), но мне еще нужно изменить этот массив в C++?

Код

        int[] pole;
        [DllImport("Sudoky(dll).dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern bool StartSudokyProfi(int[] pol, ref int[] po);
        [MarshalAs(UnmanagedType.LPArray, SizeConst = 81)]
        int[] ff;
        private void button1_Click(object sender, EventArgs e)
        {
            int num = 0;
            for (int j = 0; j < 81; j++)
            {
                if (Textbox[num].Text == "")
                    pole[num] = 0;
                else
                    pole[num] = Convert.ToInt32(Textbox[num].Text);
                num++;
            }
            ff = new int[81];
            bool b = StartSudokyProfi(pole, ref ff);
        }


Код

extern "C" __declspec(dllexport) bool StartSudokyProfi(int (pol[]),int *&po,bool flag/*= false*/ )
{
    bool b; 
    int num = 0;
    int pp[9][9];
    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9; j++)
        {
            pp[i][j] = pol[num++];
        }
    }
    Pole map(pp);
    b = map.startpodsch();
    num = 0;
    for (int i = 0; i < 9; i++)
        for (int j = 0; j < 9; j++)
        {
            po[num] = map.pole[i][j];
            num++;
        }
    return b;
}


Я не понимаю смысла: [MarshalAs(UnmanagedType.LPArray, SizeConst = 81)], мне казалось что эта строчка выделяет память для массива, но массив остается равен null, а при po[num] = map.pole[i][j]; возникает ошибка: Запись или чтение из защищенной памяти. Но при создании массива: ff = new int[81]; ошибка исчезает но массив после функции StartSudokyProfi содержит только один элемент

Автор: Ky7m 16.6.2011, 11:38
По поводу передачи массива из одного вида памяти в другую. Почему нельзя попробывать передавать массив следующим образом:

Код


\\*.h

extern "C" __declspec(dllexport) void SetInput(double [][4096]);

--------
\\*.cpp
__declspec(dllexport) void SetInput(double arrayData[][4096]);
{
       arrayData[0][6] =5.1;
}



А импорт с Dll примерно такой:

Код

 [DllImport(LibPath, EntryPoint = "SetInput", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern void p_SetInput(double[,] arrayData)


И я бы возвращал обработанный массив выходным параметром функции.

Автор: jonie 16.6.2011, 12:18
Цитата(kiler4747 @  15.6.2011,  18:41 Найти цитируемый пост)
Я не понимаю смысла: [MarshalAs(UnmanagedType.LPArray, SizeConst = 81)], мне казалось что эта строчка выделяет память для массива

она просто подсказывает CLR что при маршалинге память под эту штуку (в размере 81 элемента) не надо переносить (при сжатии) или удалять (при отработке GC) .. наверно.. читайте MSDN ... 

еще посмотрите на PInvoke.net примеры функций WinAPI которые возращают данные - что там написано..

Автор: kiler4747 16.6.2011, 17:05
Разобрался:
[DllImport("Sudoky(dll).dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool StartSudokyProfi(ref int[] pol, [MarshalAs(UnmanagedType.LPArray, SizeConst = 81)] ref int[] po);

Какой параметр в функции C++ нужно прописать чтобы можно было передавать 2-х мерные масссивы?

Код

extern "C" __declspec(dllexport) bool StartSudokyProfi(int **&pol)


Код

public static extern bool StartSudokyProfi([MarshalAs(UnmanagedType.LPArray, SizeConst = 81)] ref int[,] pol);


Возникает ошибка: Чтение или запись в защищенную память.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)