PInvoking函数成功,但未接收到结构体值
我有一个 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 有关,但我无法向我解释我做错了什么。
I have an ANSI DLL which has a function declared as follows:
long GetInfo(
THE_INFO* pINFO
)
The structure THE_INFO is declared as follows:
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;
The DLL documentation says that all functions use the stdcall calling convention for passing parameters. Further it defines:
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.
A COM wrapper DLL I used years ago is no longer supported and so I have to deal with the DLL directly. I declared the DLL call and structure in my code as follows:
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)
The function call succeeds indicating this in returning zero, so at least everything seems to be declared correctly. But when I look into the returned Info structure, all structure members are still reflecting the initial values. But at least the nWidth and nHeight members must have values greater than zero since the underlying data is a valid object.
I think it has something to do with the pinvoking, but I can't explain to me, what I have done wrong.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通常,您可以使用 Structure 关键字声明结构并传递它 ByRef:
将其声明为 Class 也可以,但随后您必须传递 ByVal 并明确告诉 pinvoke 编组器该对象需要被编组回来。像这样:
正是缺少
属性导致了您的问题。您还需要
,因为您初始化了结构的 dwSize 成员。You would normally declare the structure with the Structure keyword and pass it ByRef:
Declaring it as a Class is okay too but then you'll have to pass it ByVal and tell the pinvoke marshaller explicitly that the object needs to be marshaled back. Like this:
It is the missing
<Out>
attribute that is causing your problem. You also need<In>
since you initialize the dwSize member of the structure.