Вопрос по pinvoke, .net, c#, interop, marshalling – Как выстроить массив структур переменного размера? C # и C ++ помощь по взаимодействию

14

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

struct InnerStruct
{
   int A;
   int B;
};

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

И функция C ++

OuterStruct getStructs();

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

struct OuterStruct {
   InnerStruct[] innerStructs;
};

Ваш Ответ

1   ответ
22

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

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 из вашего кода C #, вы должны использовать стандартный распределительCoTaskMemAlloc в вашем коде C ++ - тогда вы можете позвонитьMarshal.CoTaskMemFree чтобы бесплатноinnerStructs.

Обратите внимание, что действительно крайне плохая идея разыгратьIntPtr вint в таком случае, что. Пожалуйста, не делайте!
@ doug65536 Да, ой! Исправлена! (8 лет спустя)
Не то, чтобы я знал, но я никогда не смотрел. :-)
Вы бросили указатель наint? Что если он работает в 64-битном процессе ?!You don't need the casts
Крутой мужик, спасибо большое. Также, в качестве быстрого вопроса, возможно ли маршалировать вектор, чтобы у OuterStruct был вектор InnerStructs? Я знаю, что вы не можете проводить уроки маршала, но я подумал, что, возможно, кто-то написал что-то хитрое для этого. DevDevDev

Похожие вопросы