Мне удалось передать неровный массив C # в C ++ с помощью внешнего метода Pinvoke без использования небезопасного кода C #, как в примере кода ниже.Но у меня все еще есть опасения относительно GC в режиме без отладки, вызывающего нежелательный побочный эффект.Вот фрагмент тестового кода (который работает в режиме отладки):
[Test, Ignore]
public void Test_JaggedArrayPInvoke()
{
var jaggedArray = new int[3][];
jaggedArray[0] = new int[1] { 9 };
jaggedArray[1] = new int[4] { 1, 2, 3, 8 };
jaggedArray[2] = new int[2] { 1, 2 };
//GCHandle mainHandle = GCHandle.Alloc(jaggedArray, GCHandleType.Pinned); //This does not work
var pinnedHandles = new GCHandle[3];
var jaggedArrayPtrs = new IntPtr[3];
for (int i = 0; i < 3; i++)
{
pinnedHandles[i] = GCHandle.Alloc(jaggedArray[i], GCHandleType.Pinned);
jaggedArrayPtrs[i] = pinnedHandles[i].AddrOfPinnedObject();
}
var result = JaggedArrayPInvoke_TEST(jaggedArrayPtrs);
Console.WriteLine(result); //returns 8 as it should.
//mainHandle.Free();
for (int i = 0; i < 3; i++)
{
pinnedHandles[i].Free();
}
}
//The C++ test method:
extern "C" __declspec(dllexport) int __stdcall JaggedArrayPInvoke_TEST(int** jaggedArray);
__declspec(dllexport) int __stdcall JaggedArrayPInvoke_TEST(int** jaggedArray)
{
return jaggedArray[1][3];
}
Если я должен раскомментировать часть mainHandle, я получу исключение аргумента «Объект содержит не примитивные или неблизкие данные». Так можно ли закрепить jaggedArray и действительно ли это нужно? (Я смутно напоминаю, что GC в режиме выпуска может вспомнить память уже в методах, если она больше не используется.) Хотя я думаю, что поворотВместо этого jaggedArray в переменную поля класса сделает его безопасным с точки зрения GC.