#c# #arrays #struct #marshalling #unsafe
#c# #массивы #структура #сортировка #небезопасно
Вопрос:
как мне объявить массив фиксированного размера структурного типа в C# :
[StructLayout(LayoutKind.Sequential,Pack=1), Serializable]
public unsafe struct MyStruct{
...
}
public class MyClass {
...
public fixed MyStruct myStruct[256];
}
это приведет к CS1663: буферы фиксированного размера типа struct недопустимы, как мне обойти это?, Я предпочитаю не использовать C # или тип «Структура данных управляемой коллекции», так как мне нужно часто маршалировать это на родной C
Ответ №1:
Если ваша структура C # использует только примитивные типы данных и имеет точно такую же компоновку, что и ваша собственная структура в C , вы можете обойти эти ограничения с помощью ручного управления памятью и небезопасного кода. В качестве бонуса вы улучшите производительность, избежав маршалинга.
Выделить память:
IntPtr arr = Marshal.AllocHGlobal (sizeof (MyStruct) * 256);
По сути malloc
, это означает, что выделенная память находится вне поля зрения GC.
Вы можете передать IntPtr в машинный код, как если бы это был a MyStruct[256]
, и маршалироваться будет только IntPtr, а не память, на которую он указывает. Собственный и управляемый код могут обращаться к одной и той же памяти напрямую.
Для чтения / записи структур в массиве с помощью C # используйте указатели C #:
static unsafe MyStruct GetMyStructAtIndex (IntPtr arr, int index)
{
MyStruct *ptr = ((MyStruct *)arr) index;
return *ptr;
}
static unsafe void SetMyStructAtIndex (IntPtr arr, int index, MyStruct value)
{
MyStruct *ptr = ((MyStruct *)arr) index;
*ptr = value;
}
Не забудьте
Marshal.FreeHGlobal (arr);
когда вы закончите с памятью, перейдите к free
ней.
Ответ №2:
Вы не можете; согласно определению
Единственным ограничением является то, что тип массива должен быть
bool
,byte
,char
,short
,int
,long
,sbyte
,ushort
,uint
,ulong
,float
, илиdouble.
Комментарии:
1. @uray единственное, что я могу предложить, — это обычный массив. Если это невозможно, тогда…