首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi 10.4编译器错误:“实际变量和形式变量的类型必须相同”

Delphi 10.4编译器错误:“实际变量和形式变量的类型必须相同”
EN

Stack Overflow用户
提问于 2022-06-12 17:44:37
回答 1查看 163关注 0票数 0

我对编程很陌生。我正在使用Delphi10.4社区版。我正在尝试运行BassPlayer演示项目,但是在编译和运行它时会出现一个错误。它发生在第1691行中名为wa_ipc.pas的文件中。我不知道如何纠正这个错误。

代码语言:javascript
复制
function SendMessageRetStr(wnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): String;
var
  dwProcessId: DWORD;
  phandle: THandle;
  P: Pointer;
  C: Cardinal;
  PB: Pointer;
  B: Byte;
begin
  Result := '';
  GetWindowThreadProcessID(wnd, pointer(dwProcessId));
  phandle := OpenProcess(PROCESS_VM_READ, False, dwProcessId);
  if phandle = 0 then exit;
  P := Pointer(SendMessage(wnd, uMsg, wParam, lParam));
  PB := nil;
  B := 0;
  repeat
    if not ReadProcessMemory(phandle,P,@PB,1,C) then break; (*<-- Error message here*)
    B := Byte(PB);
    if B <> 0 then begin
      Result := Result + Chr(B);
    end;
    P := Pointer(DWord(P)+1);
  until (B=0);

  CloseHandle(phandle);
end;

我得到的错误是:

dcc32 Error wa_ipc.pas(1691):实际变量和形式变量的E2033类型必须相同

Winapi.Windows.pas单元中,ReadProcessMemory()函数声明为:

代码语言:javascript
复制
function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: SIZE_T; var lpNumberOfBytesRead: SIZE_T): BOOL; stdcall;
EN

回答 1

Stack Overflow用户

发布于 2022-06-12 23:14:30

我发现这段代码有很多问题。

  • ,您在GetWindowThreadProcessId()的第二个参数中使用了pointer(dwProcessId)。它在运行时不能像预期的那样工作。您正在传递要写入的API的无效内存地址,从而导致未定义的行为。您需要使用@dwProcessId代替.

  • ReadProcessMemory()的第三个参数中使用@PB是错误的。您正在将一个字节从远程进程读取到一个Pointer变量中,然后将该Pointer截断为一个Byte。虽然这在运行时会像预期的那样运行,但在逻辑上是错误的,您确实应该使用@B,并完全摆脱PB

  • ReadProcessMemory()的第五个参数中使用C是错误的。这是编译器错误的原因。在Win32 API中,该参数需要指向SIZE_T的指针(该指针大小为无符号整数),而不是Cardinal的值(该值为固定大小的32位无符号整数)。在Delphi的Winapi.Windows单元中,该参数被声明为对SIZE_T变量的var引用,而不是对Cardinal变量的var引用,因此您将获得编译器错误。必须声明变量与var引用所期望的数据类型完全相同。

  • 所讨论的远程数据显然是一个8位以空结尾的ANSI字符串,但您正在将8位字符附加到16位UnicodeString中。除非所讨论的字符纯粹是ASCII,否则结果将不是您所期望的。

  • --在递增Dword值时,您正在将P指针转换为DwordDword是一个32位整数,所以只有当应用程序编译为32位可执行文件时,转换才能正确工作,而32位可执行文件在运行时使用32位内存地址。但是在64位可执行文件中,您可能会截断指针所指向的内存地址。您需要使用DWORD_PTR (或等效的)代替.

现在,所有这些都说了,尝试更像这样的东西而不是:

代码语言:javascript
复制
function SendMessageRetStr(wnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): String;
var
  dwProcessId: DWORD;
  hProcess: THandle;
  PCh: LRESULT;
  bytesRead: SIZE_T;
  Ch: AnsiChar;
  S: AnsiString;
begin
  Result := '';
  GetWindowThreadProcessID(wnd, @dwProcessId);
  hProcess := OpenProcess(PROCESS_VM_READ, False, dwProcessId);
  if hProcess = 0 then Exit;
  try
    PCh := SendMessage(wnd, uMsg, wParam, lParam);
    repeat
      if not ReadProcessMemory(hProcess, Pointer(PCh), @Ch, 1, bytesRead{or: PSize_t(nil)^}) then break;
      if Ch = #0 then break;
      S := S + Ch;
      Inc(PCh);
    until False;
  finally
    CloseHandle(hProcess);
  end;
  Result := string(S);
end;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72594565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档