Маршалинг неизвестного размера массива

У вас есть структура, которая принимает массив байтов

byte[]

однако размер этого массива зависит от изображения, которое вы отправляете (ширина x высота)

Итак... как дела?

[MarshalAs(UnmanagedType.ByValArray, SizeConst = ???)]
public Byte[] ImageData;

Является ли sizeconst ДОЛЖНЫ ИМЕТЬ при работе с байтовыми массивами, передаваемыми из С# в C dll?


person Olewolfe    schedule 06.08.2009    source источник
comment
Пользовательский маршаллер кажется единственным выбором.   -  person IS4    schedule 10.02.2017


Ответы (1)


Вам нужно изменить тип сортировки. SizeConst требуется, если вы маршалируете как ByValArray, но не с другими типами. Подробнее см. в перечислении UnmanagedType. .

Я подозреваю, что вы хотите маршалировать как указатель C на массив:

[MarshalAs(UnmanagedType.LPArray)]

Это приведет к маршаллингу в стандартный массив C (BYTE*), так что будет передаваться только указатель. Это позволяет передавать массив любого размера. Как правило, вы также захотите передать размер массива в качестве другого параметра (или ширины/высоты/bpp изображения, которые предоставляют ту же информацию), поскольку в C/C++ нет способа легко определить это.

person Reed Copsey    schedule 06.08.2009
comment
Спасибо за ответ Рид. Тем не менее, я сделал это и теперь получаю эту ошибку. Недопустимая комбинация управляемого/неуправляемого типа (поля массивов должны быть соединены с ByValArray или SafeArray). При построении IntPtr, а затем Marshal.StructureToPtr... Мысли? - person Olewolfe; 06.08.2009
comment
Проверьте перечисление. Потребуется больше информации. Я предполагал, что вы маршалируете из управляемого -> неуправляемого, но если вы идете наоборот, вы можете либо маршалировать его как IntPtr (вместо byte[]), либо настроить его для использования SafeArray. - person Reed Copsey; 06.08.2009
comment
К сожалению, использование чего-либо, кроме [MarshalAs(UnmanagedType.ArrayByVal, sizeConst = xxxx)], искажает адресацию памяти. Таким образом, существует структура (которая содержит byte[]), которую необходимо преобразовать в IntPtr, чтобы ее можно было передать в DLL. И данные в byte[] перепутались. Проверил это, скопировав данные из IntPtr в byte[] и просмотрев данные, чтобы обнаружить, что все изменилось, если только я не установил MarshalAs в структуре. - person Olewolfe; 07.08.2009
comment
@Olewolfe то же самое происходит со мной с двойным массивом. Я использую PInvoke от управляемого до неуправляемого. Мой двойной массив также находится внутри структуры. Согласно данным MSDN, одномерный массивы непреобразуемых типов [сами являются непреобразуемыми]. Однако тип, содержащий массив переменных непреобразуемых типов, сам по себе не преобразовывается. Я думаю, это означает, что сам ваш массив байтов считается непреобразуемым, но как только вы помещаете массив в структуру, структура теряет свою непреобразуемость. - person Ben; 22.02.2015
comment
Согласно эта статья способ обойти это — использовать SAFEARRAY. - person Ben; 22.02.2015