PInvoking函数成功,不接收结构值

时间:2012-02-04 12:33:21

标签: .net vb.net data-structures pinvoke

我有一个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.

我不再支持多年前使用的COM包装器DLL,所以我必须直接处理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成员必须具有大于零的值,因为基础数据是有效对象。

我认为它与pinvoking有关,但我无法向我解释,我做错了什么。

1 个答案:

答案 0 :(得分:2)

您通常会使用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 marshaller该对象需要被编组回来。像这样:

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

导致问题的是缺少的<Out>属性。因为初始化结构的dwSize成员,所以还需要<In>