Вызов функций из неуправляемой библиотеки DLL

#c# #dll #unmanaged

#c# #dll #неуправляемый

Вопрос:

У меня есть неуправляемая библиотека DLL со следующими функциями:

 ReadLatch( HANDLE cyHandle,
                LPWORD  lpLatch);


WriteLatch(HANDLE cyHandle,
                WORD    mask,
                WORD    latch);



GetPartNumber(HANDLE cyHandle,
                   LPBYTE   lpbPartNum);

 GetDeviceProductString(HANDLE  cyHandle,
                            LPVOID  lpProduct,
                            LPBYTE  lpbLength,
                            BOOL    bConvertToASCII = TRUE
                            );


GetDeviceSerialNumber(HANDLE   cyHandle,
                           LPVOID   lpSerialNumber,
                           LPBYTE   lpbLength,
                           BOOL     bConvertToASCII = TRUE
                           );


 GetDeviceInterfaceString(HANDLE    cyHandle,
                              LPVOID lpInterfaceString,
                              LPBYTE lpbLength,
                              BOOL bConvertToASCII);
  

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

 [DllImportAttribute("runtime.dll", EntryPoint = "ReadLatch", CallingConvention =     CallingConvention.Cdecl)]
    static extern int ReadLatch(HANDLE cyHandle, [MarshalAs(UnmanagedType. ??????)] ?????? lpLatch);

    [DllImportAttribute("runtime.dll", EntryPoint = "WriteLatch", CallingConvention = CallingConvention.Cdecl)]
    static extern int WriteLatch(HANDLE cyHandle,
                WORD mask,
                WORD latch);

    [DllImportAttribute("runtime.dll", EntryPoint = "GetPartNumber", CallingConvention = CallingConvention.Cdecl)]
    static extern int GetPartNumber(HANDLE cyHandle,
                   LPBYTE lpbPartNum);

    [DllImportAttribute("runtime.dll", EntryPoint = "GetDeviceProductString", CallingConvention = CallingConvention.Cdecl)]
    static extern int GetDeviceProductString(HANDLE cyHandle,
                            LPVOID lpProduct,
                            LPBYTE lpbLength,
                            BOOL bConvertToASCII = TRUE
                            );

    [DllImportAttribute("runtime.dll", EntryPoint = "GetDeviceSerialNumber", CallingConvention = CallingConvention.Cdecl)]
    static extern int GetDeviceSerialNumber(HANDLE cyHandle,
                           LPVOID lpSerialNumber,
                           LPBYTE lpbLength,
                           BOOL bConvertToASCII = TRUE
                           );

    [DllImportAttribute("runtime.dll", EntryPoint = "GetDeviceInterfaceString", CallingConvention = CallingConvention.Cdecl)]
    static extern int GetDeviceInterfaceString(HANDLE cyHandle,
                              LPVOID lpInterfaceString,
                              LPBYTE lpbLength,
                              BOOL bConvertToASCII);
  

Где я могу найти информацию о том, как представлять HANDLE, LPWORD и другие, чтобы я мог вызывать функции?

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

1. См. раздел Типы данных, вызываемые платформой

Ответ №1:

Неуправляемые типы и их управляемые аналоги:

  • HANDLE обычно представлен IntPtr .
  • WORD UInt16

Для других функций нам может потребоваться узнать немного больше о том, как они используются.

Надеюсь, к вашему API есть какая-то сопроводительная документация, которая объясняет, что делают параметры, поскольку некоторые из них не совсем очевидны.

Для этой функции мы можем сделать некоторые предположения:

 ReadLatch(HANDLE cyHandle, LPWORD  lpLatch);
  

Предполагая, что lpLatch это действительно параметр «out» (и ваш возвращаемый тип int ):

 [DllImportAttribute("runtime.dll", EntryPoint = "ReadLatch", CallingConvention = CallingConvention.Cdecl)]
static extern int ReadLatch(IntPtr cyHandle, out UInt16 lpLatch);
  

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

1. Спасибо. Я собираю это вместе, надеюсь, все это работает.

2. Проблема заключается в том, что что-то вроде LPBYTE может быть «out parameter» (вы передаете ему адрес переменной, из которой вы получаете данные), или это может быть указатель на массив … это зависит от документации, чтобы уточнить, в каком случае.

3. Да, это так. все переменные lp являются выходными данными (указателями в исходном коде).

4. Тогда вы должны иметь возможность просто использовать параметры в своих сигнатурах C #.