Массив фиксированного размера типа структуры

#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 единственное, что я могу предложить, — это обычный массив. Если это невозможно, тогда…