Функция PInvoking завершается успешно, не получая значения структуры - PullRequest
0 голосов
/ 04 февраля 2012

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

long GetInfo(
   THE_INFO* pINFO
) 

Структура THE_INFO объявлена ​​следующим образом:

typedef struct tagTHE_INFO
{
   unsigned long dwSize;
   char          szCopyright[64];
   long          nWidth;
   long          nHeight;
   long          nObjectCount;
   int           bThumbnailImage;
   long          nThumbnailImageWidth;
   long          nThumbnailImageHeight;
   int           bThumbnailObject;
   long          nThumbnailObjectWidth;
   long          nThumbnailObjectHeight;
} 
THE_INFO;

В документации DLL сказано, что все функции используют соглашение о вызовах stdcall для передачи параметров. Далее он определяет:

unsigned long    As Unsigned 32-bit integer.
char             As Signed 8-bit integer.
long             As Signed 32-bit integer.
int              As Signed 32-bit integer.

DLL-оболочка COM, которую я использовал несколько лет назад, больше не поддерживается, поэтому мне приходится иметь дело с DLL напрямую. Я объявил вызов DLL и структуру в моем коде следующим образом:

Declare Ansi Function GetInfo Lib "ADLL.dll" (pINFO As THE_INFO) As Integer

<StructLayout(LayoutKind.Sequential)> Friend Class THE_INFO
  Public dwSize As UInteger
  <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=64)>
  Public szCopyright As String
  Public nWidth As Integer
  Public nHeight As Integer
  Public nObjectCount As Integer
  Public bThumbnailImage As Integer
  Public nThumbnailImageWidth As Integer
  Public nThumbnailImageHeight As Integer
  Public bThumbnailObject As Integer
  Public nThumbnailObjectWidth As Integer
  Public nThumbnailObjectHeight As Integer
End Class


Dim Info As New THE_INFO With {.dwSize = 104}
ErrorCode = GetInfo(Info)

Вызов функции завершается успешно, показывая, что возвращается ноль, поэтому, по крайней мере, все, кажется, объявлено правильно. Но когда я просматриваю возвращенную структуру Info, все элементы структуры все еще отражают начальные значения. Но, по крайней мере, члены nWidth и nHeight должны иметь значения больше нуля, поскольку базовые данные являются допустимым объектом.

Я думаю, что это как-то связано с пинвокингом, но я не могу объяснить, что я сделал неправильно.

1 Ответ

2 голосов
/ 04 февраля 2012

Обычно вы объявляете структуру с помощью ключевого слова Structure и передаете ее ByRef:

<StructLayout(LayoutKind.Sequential)> _
Friend Structure THE_INFO
    '' etc..
End Structure

Declare Ansi Function GetInfo Lib "ADLL.dll" (ByRef pINFO As THE_INFO) As Integer

Можно также объявить ее как класс, но тогда вам придется передать ее ByVal и сообщить маршаллу pinvokeявно, что объект нужно маршалировать обратно.Например:

Declare Ani Function GetInfo Bar Lib "ADLL.dll" (<[In](), Out()> ByVal pINFO As THE_INFO) As Integer

Отсутствующий атрибут <Out> вызывает вашу проблему.Вам также нужно <In>, так как вы инициализируете член структуры dwSize.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...