Маршалировать массив классов C # как структурный массив на C

#c# #arrays #interop #struct #marshalling

#c# #массивы #взаимодействие #структура #маршалирование

Вопрос:

Вот мой код:

 [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Foo
{
  UInt32 StartAddr;
  UInt32 Type;
}


[DllImport(DllName, EntryPoint="_MyFunc", CallingConvention = CallingConvention.Cdecl)]
static extern unsafe IntPtr MyFunc([MarshalAs(UnmanagedType.LPArray)] Foo[] Foos);


List<Foo> Foos = new List<Foo>();
Foo1 = new Foo();
Foo1.StartAddr = 1;
Foo1.Type = 2;
Foos.Add(Foo1);
MyFunc(Foos.ToArray());
  

В C-based DLL я распечатываю значение Foos[0].StartAddr и Foos[0].Введите. Это отлично работает.

Теперь я хочу добавить конструктор без параметров в структуру, что означает, что я должен переключиться на класс. Только изменение объявления C # с «struct» на «class» приводит к передаче поврежденных значений в библиотеку DLL на основе C.

Я считаю, что это должно сработать, но я предполагаю, что я пропускаю шаг. Как я могу передать массив классов C # в виде массива структур в C-код?

Спасибо! Энди

Комментарии:

1. Да, не сработает. Массив будет маршалирован как Foo** вместо Foo* . Массив указателей на Foo. Чистого обходного пути также нет, ручная маршалировка здесь очень уродлива. Не делайте этого, если вы не можете изменить код C.

Ответ №1:

Если вам нужен элемент по умолчанию в вашей структуре, вы можете добавить к нему статическое свойство

     [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct Foo
    {
      UInt32 StartAddr;
      UInt32 Type;

      public static Foo Default
      {
          get 
          {
               Foo result = new Foo();
               result.StartAddr = 200;
               result.Type = 10;
               return resu<
          }
      }
    }
  

И когда вам нужно создать новую Foo структуру, просто вызовите Foo.Default