指针的封送结构 - Byte 是 OK,Byte() 是 Not OK

Marshal structure to pointer - Byte is OK, Byte() is Not OK

提问人:Manuel 提问时间:11/10/2023 最后编辑:GSergManuel 更新时间:11/10/2023 访问量:87

问:

我正在尝试从结构中获取指针,将其传递给非托管DLL。

奇怪的是,如果我使用这个结构,如下:

Structure message
    Public x As Byte
End Structure

并像这样构建指针:

Dim mess As message = New message With {.X = &H33}
Dim sizeOfHeader As Integer = 1

Dim pHeader As IntPtr = Marshal.AllocHGlobal(sizeOfHeader)

Marshal.StructureToPtr(mess, pHeader, True)

一切都很好 - 我可以将指针传递到我的非托管应用程序,并获取正确的信息。

但是,如果我使用此结构(使用字节数组 - 因为我需要多个字节 - 将来具有可变长度):

Structure message
    Public x As Byte()
End Structure

并像这样构建指针:

Dim mess As message = New message With {.X = New Byte() {&H33}}
Dim sizeOfHeader As Integer = 1

Dim pHeader As IntPtr = Marshal.AllocHGlobal(sizeOfHeader)

Marshal.StructureToPtr(mess, pHeader, True)

失败 - 非托管应用程序接收的数据是随机的(不是0x33)

我在这里做错了什么?

编辑:

有时我还会得到一个

System.AccessViolationException:“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。

从函数。Marshal.StructureToPtr

此外,有时调试器仅以代码0xc0000374结束(似乎是),但没有其他信息。STATUS_HEAP_CORRUPTION

vb.net 指针 结构 封送非 托管

评论

0赞 jmcilhinney 11/10/2023
我的猜测是您必须将该字段应用于该字段。MarshalAsAttribute
1赞 Jimi 11/10/2023
你为什么要设置在那里?用于确定结构的大小(当然,当字段表示数组时,不是)。然后,这取决于对方的期望。如果需要固定大小的数组,请将该数组封送为 .sizeOfHeader1Marshal.SizeOf1ByValArray
0赞 Manuel 11/10/2023
您好,感谢您的回复。大小无关紧要,它只是设置为 1 用于测试目的。我将尝试使用 MarshalAsAttribute 字段,并通知您
0赞 Nick Abbot 11/10/2023
我猜,是 Value 类型,但 Reference 类型。因此,当您使用 时,您正在编组指向指针的指针。ByteByte()Byte()
0赞 GSerg 11/10/2023
@Manuel 大小非常重要,因为您要分配 1 个字节的内存,然后在其中写入更多字节。为什么一开始就要手动获取指针?不需要“将其传递给非托管 DLL”。

答:

-1赞 Nick Abbot 11/10/2023 #1

我认为当你使用时,你真正想要的是:Byte()

Marshal.StructureToPtr(mess.x(0), pHeader, True)

您需要结构中第一个字节的地址。