我有一个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有关,但我无法向我解释,我做错了什么。
答案 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>
。