RMInformatique Ответов: 1

Как получить доступ к struct C с помощью обратного вызова в C#


Привет,

Мне нужно получить доступ к библиотеке C dll. эта библиотека dll имеет обратный вызов.
Но когда вызывается обратный вызов, у меня есть исключение.

Это описание моей библиотеки dll C

typedef struct am3_oem_device
{
   unsigned int number_sensor_width;
   unsigned int number_sensor_height;
   float sensor_surface_cm2;
   char* serial;
   char* am3_id;
   char* bootloader_firmware;
   char* micro_firmware;
   char* cpld_firmware;
   char* wifi_firmware;
   char* hardware_version;
   }AM3_OEM_DEVICE ;


  typedef struct am3_oem_device_manager
  {
      void (*device_has_connected)(AM3_OEM_DEVICE device_connected);
      void (*device_has_disconnected)(AM3_OEM_DEVICE device_disconnected);
      void (*device_status_update)(AM3_OEM_DEVICE device, unsigned int status);
      void (*device_acquisition_available)(AM3_OEM_DEVICE device, unsigned int* millisecond, unsigned int size);

  }*P_AM3_OEM_DEVICE_MANAGER,AM3_OEM_DEVICE_MANAGER;


Что я уже пробовал:

Это код C#, связанный с ним
[StructLayout(LayoutKind.Sequential)]
public struct AM3_OEM_DEVICE
{
    public uint number_sensor_width;
    public uint number_sensor_height;
    public float sensor_surface_cm2;

    [MarshalAs(UnmanagedType.LPStr)]
    public StringBuilder serial;

    [MarshalAs(UnmanagedType.LPStr)]
    public StringBuilder am3_id;

    [MarshalAs(UnmanagedType.LPStr)]
    public StringBuilder bootloader_firmware;

    [MarshalAs(UnmanagedType.LPStr)]
    public StringBuilder micro_firmware;

    [MarshalAs(UnmanagedType.LPStr)]
    public StringBuilder cpld_firmware;

    [MarshalAs(UnmanagedType.LPStr)]
    public StringBuilder wifi_firmware;

    [MarshalAs(UnmanagedType.LPStr)]
    public StringBuilder hardware_version;
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void device_has_connected(AM3_OEM_DEVICE device_connected);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void device_has_disconnected(AM3_OEM_DEVICE device_connected);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void device_status_update(AM3_OEM_DEVICE device_connected, uint status);
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
delegate void device_acquisition_available(AM3_OEM_DEVICE device_connected, out uint millisecond, uint size);


[StructLayout(LayoutKind.Sequential)]
public struct AM3_OEM_DEVICE_MANAGER
{
    private device_has_connected device_has_connected;
    private device_has_disconnected device_has_disconnected;
    private device_status_update device_status_update;
    private device_acquisition_available device_acquisition_available;

}


У меня определенно есть ошибка в моем коде Маршалла.
Можете ли вы помочь мне, пожалуйста?
Спасибо.

1 Ответов

Рейтинг:
9

RMInformatique

я нашел решение

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
       public delegate void device_has_connected(AM3_OEM_DEVICE device_connected);
       [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
       public delegate void device_has_disconnected(AM3_OEM_DEVICE device_connected);
       [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
       public delegate void device_status_update(AM3_OEM_DEVICE device_connected, uint status);
       [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
       public delegate void device_acquisition_available(AM3_OEM_DEVICE device_connected, ref uint millisecond, uint size);

       [StructLayout(LayoutKind.Sequential)]
       public struct AM3_OEM_DEVICE_MANAGER
       {
           public IntPtr DeviceHasConnected;
           public IntPtr DeviceHasDisconnected;
           public IntPtr DeviceStatusUpdate;
           public IntPtr AcquisitionAvailable;
       }

Вы называете структуру с

g_device_manager = new AM3_OEM_DEVICE_MANAGER
  {
      DeviceHasConnected = Marshal.GetFunctionPointerForDelegate(new device_has_connected(DeviceHasConnected)),
      DeviceHasDisconnected = Marshal.GetFunctionPointerForDelegate(new device_has_connected(DeviceHasDisconnected)),
      DeviceStatusUpdate = Marshal.GetFunctionPointerForDelegate(new device_status_update(DeviceStatusUpdate)),
      AcquisitionAvailable = Marshal.GetFunctionPointerForDelegate(new device_acquisition_available(DeviceAcquisitionAvailable))
  };