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
相关产品推荐
相关产品推荐

