C # PInvoke передает ссылку на int [] - PullRequest
0 голосов
/ 25 октября 2019

Я пытаюсь передать ссылку int [8] на C ++ DLL, но System.ExecutionEngineException выбрасывается в C # при возврате. Вот код C ++:

extern "C" __declspec(dllexport) int __stdcall ReadFlashCfg(int* flData);
int __stdcall ReadFlashCfg(int* flData)
{
    return mctl.ReadFlashCfg(flData);
}// breakpoint here shows flData is correct

И код оболочки C # DLL:

[DllImport(MyDllPath)]
private static extern int ReadFlashCfg(ref int[] fData);

public static int[] ReadFlashCfgNoRc()
{
   var flData = new int[8];
   var rc = ReadFlashCfg(ref flData); //Exception happens here
   if (rc != 0) throw new Exception(rc.ToString());
   return flData;
}

И код вызова C #:

var fd = ReadFlashCfgNoRc();

Точка останова наСамая последняя строка кода C ++ показывает массив, заполненный правильными данными.

Исключение возникает при возврате из ReadFlashCfg(ref flData) в оболочке DLL.

Я думаю, мне нужно сообщить C ++ размер массива (он всегда равен 8), чтобы он мог управлятьстек правильно.

Я знаю, что могу передать восемь отдельных int *, но должен быть более простой способ - есть?

1 Ответ

0 голосов
/ 29 октября 2019

Ref передать аргумент по ссылке.

Поскольку этот ответ говорит:

  • ref Int32 - правильное совпадение дляint*.
  • Int[] (указал @ DavidHeffman) и IntPtr также могут работать. (используйте Marshal::AllocHGlobal(8*sizeof(Int32)) для назначения IntPtr размера, Marshal.FreeHGlobal(IntPtr) для освобождения)
  • ref Int[] будет int**, а размер Int[] будет неправильно преобразован в 1.

Для " Мне нужно сообщить C ++ размер массива ". Обычный метод - передать размер в качестве параметра.

...