Как маршалировать массив структур с переменным размером? Поддержка С# и С++

У меня следующие структуры С++

struct InnerStruct
{
   int A;
   int B;
};

struct OuterStruct
{
   int numberStructs;
   InnerStruct* innerStructs;
};

И функция С++

OuterStruct getStructs();

Как я могу сделать это на С#? Где определения С#

struct OuterStruct {
   InnerStruct[] innerStructs;
};

Ответы

Ответ 1

Вам нужно будет сделать это вручную, так как нет способа рассказать слою P/Invoke, сколько данных необходимо вывести из возвращаемого значения С++.

struct OuterStruct {
   int numberStructs;
   IntPtr innerStructs;
};

OuterStruct s = getStructs(); // using DllImport
var structSize = Marshal.SizeOf(typeof(InnerStruct));
var innerStructs = new List<InnerStruct>();
var ptr = s.innerStructs;

for (int i = 0; i < s.numberStructs; i++)
{
    innerStructs.Add((InnerStruct)Marshal.PtrToStructure(ptr, 
        typeof(InnerStruct));
    ptr = ptr + structSize;
}

Обратите внимание, что если вы хотите освободить память для innerStructs от вашего кода С#, вам нужно использовать стандартный распределитель CoTaskMemAlloc в коде С++, тогда вы можете вызвать Marshal.CoTaskMemFree, чтобы освободить innerStructs.