Объединение с буфером массива в C # - PullRequest
0 голосов
/ 10 октября 2018

Я работал над некоторым интерфейсом, который определил буфер данных, и его можно преобразовать в связанную структуру данных в c union, как показано ниже,

union DATA_STRUCTURE {
    uint8_t buffer[BUFFER_SIZE];
    A_STRUCT a;
    B_STRUCT b;
}; 

Я могу поместить полученные данные в буфери прочитайте данные, используя a или b в соответствии с типом данных, определенным где-то в буфере.

И теперь я собираюсь переписать интерфейсную программу в c #, я не могу найти синтаксис объединения, подобный синтаксису в c #и я обнаружил, что существует много похожих постов на эту тему, предлагается реализовать с использованием FieldOffset, как показано ниже:

  [StructLayout(LayoutKind.Explicit)]
  struct MyUnion
  {
    [FieldOffset(0)] int I;
    [FieldOffset(0)] float F;
  }

Я просто пытаюсь определить структуру, как показано ниже,

  [StructLayout(LayoutKind.Explicit, Size = 16)]
  struct MyUnion
  {
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    [FieldOffset(0)] public byte[] buffer;
    [FieldOffset(0)] public A_STRUCT a;
    [FieldOffset(0)] public B_STRUCT b;
  }
  MyUnion data;

Но я не могу заполнить данные в буфере с помощью инструкции, такой как data.buffer [0] = x;Он покажет ошибку «Использование возможно неназначенного поля« буфер »».Более того, даже если я могу поместить значение в буфер, похоже, что та же ошибка будет возвращена, если я попытаюсь получить доступ к данным через a или b.

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

  byte *ptr = (byte *) &data;
  byte *ptr = data.buffer;
  byte *ptr = &data.buffer[0];

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

Могу ли я знать, если естьесть ли способ реализовать структуру объединения в C # для вышеуказанной ситуации?

Большое спасибо.

1 Ответ

0 голосов
/ 10 октября 2018

Поскольку массив является управляемым объектом (а не структурой), я не думаю, что с ним можно по-настоящему играть трюки в стиле объединения.

Я бы просто работал с простым byte[] доЯ готов преобразовать, затем получить IntPtr из массива (через fixed, вероятно) и затем использовать Marshal.PtrToStructure, чтобы получить A_STRUCT или B_STRUCT.Конечно, это больше работы, если ваши шаблоны доступа больше похожи на:

  • обрабатывать его как массив
  • обрабатывать его как A_STRUCT
  • обрабатывать егокак массив
  • рассматривать его как B_STRUCT
...