Как маршалировать структуру, содержащую указатель на первый элемент массива неизвестного типа в стиле C

Я пытаюсь маршалировать с C ++ на C # структуру, которая выглядит примерно так:

typedef struct FooStruct {
    Uint8 bytesPerThingie;
    void *arrayOfThingies;
    // other members ...
}

Итак, в этом случае есть две неизвестные:

  1. Количество элементов в массиве.
  2. Размер (в байтах) каждого элемента.

Ранее я успешно маршалировал саму структуру с таким определением:

[StructLayout(LayoutKind.Sequential)]
public struct FooStruct {
    public byte bytesPerThingie;
    public IntPtr arrayOfThingies;
    // other members...
}

но теперь мне нужно проверить и изменить встроенный массив.

Я это понимаю

  1. Сам по себе массив непреобразуемых элементов непреобразуемого типа является непреобразуемым, но не тогда, когда он используется в качестве поля в структуре.
  2. При маршалинге из неуправляемого кода в .NET Framework длина массива определяется аргументом SizeConst, за которым может следовать неуправляемый тип элементов массива, если они не являются непреобразуемыми.

Даже если предположить, что элементы в массиве в этом случае имеют непреобразуемый тип, как я могу установить SizeConst, аргумент времени компиляции, если я не могу знать размер массива до времени выполнения?


person Buggieboy    schedule 26.03.2012    source источник
comment
Вы не можете использовать SizeConst. Скорее всего, вам придется провести сортировку самостоятельно.   -  person David Heffernan    schedule 27.03.2012


Ответы (1)


Короче говоря, вы не можете. SizeConst в _ 2_ class компилируется в метаданные в поле и не может быть измененным во время выполнения (по крайней мере, не так, чтобы это принесло вам пользу).

Тем не менее, у вас есть следующие варианты:

  • Маршалируйте содержимое вручную, как вы это делали, используя методы Marshal класс.
  • Используйте unsafe для прямого доступа к указателю. (и измените свой тип, чтобы использовать указатели). Для этого требуется /unsafe параметр компилятора, который может или не может быть вариантом для вас.
  • Используйте C ++ / CLI для создания управляемая оболочка на C ++, которая будет экспортировать типы .NET, но обрабатывать маршалинг на C ++ (что может быть проще, в зависимости от вашего уровня комфорта и сложности API, к которому вы пытаетесь получить доступ).

Обратите внимание, что во всех описанных выше случаях вам все равно нужно знать длину возвращаемого массива (вероятно, он находится в структуре вместе с указателем и типом).

person casperOne    schedule 26.03.2012
comment
Спасибо, это помогает. (Да, длина массива является одним из членов структуры.) - person Buggieboy; 27.03.2012