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

Delphi 10.4编译wa_ipc.pas报E2033实参与形参类型必须相同错误

问题根因

触发E2033编译错误的直接原因是调用ReadProcessMemory时实参和形参类型不匹配:
从你贴的API声明可以看到,ReadProcessMemory最后一个输出参数lpNumberOfBytesRead是var SIZE_T类型——SIZE_T是平台相关长度的无符号整数,32位编译下占4字节,64位编译下占8字节。原代码中用来接收该值的变量C被定义为固定4字节的Cardinal类型,在Delphi 10.4默认支持64位编译的环境下类型不匹配,直接报错。

另外这段是很老的32位Delphi时代遗留的代码,还有3处会导致64位编译/运行异常的问题:

  • 调用GetWindowThreadProcessID时强行把dwProcessId转为Pointer传参属于错误写法,该函数第二个参数本身就是进程ID的输出指针,直接传变量地址即可
  • 逐字节读取目标进程内存时,错误地将Pointer类型变量PB的地址作为1字节数据的接收缓冲区,会造成栈内存越界写入
  • 做指针偏移计算时把Pointer强转为固定4字节的DWord,64位环境下会截断8字节长度的指针地址,直接导致内存读取失败
修复方案

直接替换原函数为以下兼容32/64位编译的版本即可:

function SendMessageRetStr(wnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): String;
var
  dwProcessId: DWORD;
  phandle: THandle;
  P: Pointer;
  C: SIZE_T;
  B: Byte;
begin
  Result := '';
  GetWindowThreadProcessID(wnd, @dwProcessId);
  phandle := OpenProcess(PROCESS_VM_READ, False, dwProcessId);
  if phandle = 0 then Exit;

  P := Pointer(SendMessage(wnd, uMsg, wParam, lParam));
  B := 0;
  repeat
    if not ReadProcessMemory(phandle, P, @B, 1, C) then Break;
    if B <> 0 then
      Result := Result + Chr(B);
    P := Pointer(NativeInt(P) + 1);
  until B = 0;

  CloseHandle(phandle);
end;
改动说明
  • 将变量C的类型从Cardinal修改为SIZE_T,完全匹配API的参数类型要求,直接解决当前编译报错
  • 删除多余的PB变量,直接用B: Byte作为单字节读取的缓冲区,修复原代码的栈越界问题
  • 修正GetWindowThreadProcessID的传参逻辑,去掉错误的类型强转
  • 指针偏移计算时使用NativeInt(长度和指针一致的平台相关整数类型)做算术,避免64位下指针截断

内容的提问来源于stack exchange,提问作者TomJones965

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 20:51:20