You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中如何将字节数组指针传递给非托管Windows API函数

直接传递固定字节数组指针调用SendMessageA的实现方法

完全可以直接传递固定字节数组的指针来调用SendMessageA,不用额外创建字符串实例,具体实现步骤如下:

1. 修改SendMessageA的API声明

把原来lParam As String改成lParam As IntPtr,因为我们要传递的是内存地址指针:

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer

2. 获取固定字节数组的指针并调用API

你已经用GCHandle.Alloc固定了字节数组,直接用AddrOfPinnedObject()就能拿到数组的首地址指针,然后传给lParam参数即可:

Dim b(20) As Byte
' 初始化字节数组,确保末尾是0(这里数组默认初始化为0,只设置第一个元素为65即字符'A')
b(0) = 65

Dim bHandle As GCHandle = GCHandle.Alloc(b, GCHandleType.Pinned)
Try
    ' 获取固定数组的首地址指针
    Dim arrayPtr As IntPtr = bHandle.AddrOfPinnedObject()
    ' 调用SendMessageA,直接传递指针
    Dim h As Integer = SendMessage(cH, &HC, 0, arrayPtr)
Finally
    ' 必须释放GCHandle,避免内存泄漏
    bHandle.Free()
End Try

关键注意事项

  • 零终止符要求:SendMessageA的ASCII字符串参数必须是以0字节结尾的,你的代码里数组默认元素都是0,所以只设置b(0)=65后,后面的字节都是0,满足要求;如果是手动填充多个字符,一定要记得在最后加一个0字节作为终止符。
  • GCHandle的释放:固定数组后必须在Finally块里调用Free(),不然会造成内存泄漏,这点很重要。
  • 封送逻辑说明:原来用String类型时,.NET会自动把字符串封送为ASCII编码的零终止字节数组并传递指针;现在我们手动固定数组并传递指针,本质上是跳过了.NET自动封送字符串的步骤,直接给API传递了它需要的原始内存地址,完全符合SendMessageA的参数要求。

内容的提问来源于stack exchange,提问作者and his dog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 13:12:33