PInvoking函数成功,但未接收到结构体值

发布于 2025-01-03 00:34:08 字数 1736 浏览 0 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷夜 2025-01-10 00:34:08

通常,您可以使用 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

将其声明为 Class 也可以,但随后您必须传递 ByVal 并明确告诉 pinvoke 编组器该对象需要被编组回来。像这样:

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

正是缺少 属性导致了您的问题。您还需要 ,因为您初始化了结构的 dwSize 成员。

You would normally declare the structure with the Structure keyword and pass it 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

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:

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

It is the missing <Out> attribute that is causing your problem. You also need <In> since you initialize the dwSize member of the structure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文