2009-09-21 4 views
5

Я занимаюсь некоторыми работами на C#. Я имею следующую структуру:C#: сортировка структуры, содержащей массивы

#pragma pack(push,1) 
typedef struct 
{ 
    unsigned __int64 Handle; 
    LinkType_t Type; 
    LinkState_t State; 
    unsigned __int64 Settings; 
    signed __int8 Name[MAX_LINK_NAME]; 
    unsigned __int8 DeviceInfo[MAX_LINK_DEVINFO]; 
    unsigned __int8 Reserved[40]; 
} LinkInfo_t; 

Это моя попытка преобразовать его в C# структуры:

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public struct LinkInfo_t 
{ 
    [MarshalAs(UnmanagedType.U8)] 
    public UInt64 Handle; 
    MarshalAs(UnmanagedType.I4)] 
    public LinkType_t Type; 
    [MarshalAs(UnmanagedType.I4)] 
    public LinkState_t State; 
    [MarshalAs(UnmanagedType.U8)] 
    public UInt64 Settings; 
    [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_LINK_NAME)] 
    public string Name; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_LINK_DEVINFO, ArraySubType = UnmanagedType.U1)] 
    public byte[] DeviceInfo; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40, ArraySubType = UnmanagedType.U1)] 
    public byte[] Reserved; 
} 

Однако всякий раз, когда я инициализировать Составляя имя, DeviceInfo и зарезервированные поля все готово to null. Как это исправить?

ответ

7

Для массивов, попробуйте использовать fixed модификатор:

public fixed byte DeviceInfo[MAX_LINK_DEVINFO]; 
    public fixed byte Reserved[40]; 
+0

Это работает для массивов. Однако правильный синтаксис: общедоступный фиксированный байт DeviceInfo [MAX_LINK_DEVINFO]; Я также должен объявить структуру небезопасной. – 2009-09-21 15:33:15

+0

Вы правы, я исправил его –

3

всякий раз, когда я инициализировать Составляя Имя, DeviceInfo и Зарезервированные поля все установлено нулевое значение

Это правильно, и ваше определение выглядит хорошо для меня (BTW, вам не нужно [MarshalAs] в примитивных полях, поведение по умолчанию - это то, что вы там указали). Поскольку ваши поля массива null, маршалер ничего не сделает с ними, когда маршалинг вашей структуры в неуправляемую память, но при создании маркера они будут создавать строки и массивы.

+1

вместо небезопасного и исправленного, код должен выделять массивы байтов перед его использованием. Обычно у меня есть конструктор для structs для p/invoke, где автоматически распределяются любые массивы. – erict

0

Что говорит Антон Тихий. Я просто хочу пояснить некоторые примеры. Использование «фиксированных» работ, но это заставляет вас использовать «небезопасные». Мне нравится избегать использования небезопасных, когда это возможно. Использование маршала - это способ обойти это.

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

typedef struct { 
    int messageType; 
    BYTE payload[60]; 
} my_message; 

/** 
* \param[out] msg Where the message will be written to 
*/ 
void receiveMessage(my_message *msg); 

/* 
* \param[in] msg The message that will be sent 
*/ 
void sendMessage(my_message *msg); 

В C#, следующая структура была бы эквивалентна одной из С.

[StructLayout(LayoutKind.Sequential, Size = 64), Serializable] 
struct my_message 
{ 
    int messageType; 
    [MarshalAs(UnmanagedType.ByValArray,SizeConst = 60)] 
    byte[] payload; 

    public initializeArray() 
    { 
     //explicitly initialize the array 
     payload = new byte[60]; 
    } 
} 

Поскольку сообщ в receiveMessage() документирована как [выход], вам не нужно делать ничего особенного для массива в структуре, прежде чем передать его функции. т.е .:

my_message msg = new my_message(); 
receiveMessage(ref msg); 
byte payload10 = msg.payload[10]; 

Поскольку тзд в SendMessage() документирована как [в], вам нужно будет заполнить массив перед вызовом функции. Перед заполнением массива, массив должен быть явно создан, прежде чем использовать его. т.е .:

my_message msg = new my_message(); 
msg.initializeArray(); 
msg.payload[10] = 255; 
sendMessage(ref msg); 

Вызов initializeArray() должны создать экземпляр массива в ранее выделенном пространстве, созданном внутри структуры для этого массива.

Смежные вопросы