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

发布于 2025-02-06 14:45:55 字数 1296 浏览 2 评论 0原文

我是编程的新手。我正在使用Delphi 10.4社区版。我正在尝试运行Bassplayer Demo项目,但是在尝试编译和运行时会遇到错误。它发生在第1691行上的名为wa_ipc.pas的文件中。我不知道如何解决此错误。

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错误] wa_ipc.pas(1691):e2033实际和正式var参数的类型必须相同

[dcc32错误] wa_ipc.pas(1691):e2033实际和正式var参数的类型必须在winapi.windows.pas.pas单元,read> readprocessMemory()功能中 。被宣布为:

function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: SIZE_T; var lpNumberOfBytesRead: SIZE_T): BOOL; stdcall;

I'm new to programming. I'm using Delphi 10.4 Community Edition. I'm trying to run the BassPlayer demo project, but I get an error when trying to compile and run it. It happens in a file named wa_ipc.pas on line 1691. I have no idea how to fix this error.

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;

The error I get is:

[dcc32 Error] wa_ipc.pas(1691): E2033 Types of actual and formal var parameters must be identical

Within the Winapi.Windows.pas unit, the ReadProcessMemory() function is declared as:

function ReadProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: SIZE_T; var lpNumberOfBytesRead: SIZE_T): BOOL; stdcall;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

橙幽之幻 2025-02-13 14:45:56

我看到了此代码的许多问题。

  • 您使用指针(dwprocessid)getWindowThreadProcessid()的第二个参数中是错误的。 在运行时不会按预期工作。您正在传递一个无效的内存地址,供API写入,导致不确定的行为。您需要使用@dwprocessid而不是。

  • readProcessMemory()的第三参数中,您使用@pb是错误的。您正在将远程过程中的1个字节读取到指针变量中,然后您将指针截断为byte。尽管此将按照运行时的预期表现,但它是逻辑上错误的,您确实应该使用@b,然后摆脱pb完全。

  • readprocessMemory()的第5个参数中使用c是错误的。这是您编译器错误的原因。在Win32 API中,该参数期望 pointer size_t(这是指针大小的无符号整数),而不是a的 value 红衣主教(这是一个固定尺寸的32位未签名整数)。在delphi的winapi.windows单元中,该参数被声明为var引用size_t变量,而不是var引用Cardinal变量,因此为什么要获得编译器错误。您必须将变量声明与var参考所期望的完全相同的数据类型。

  • 所讨论的远程数据显然是一个8位null终止的ANSI字符串,但是您将8位字符附加到16bit Unicodestring。除非所讨论的字符纯粹是ASCII,否则结果将不是您所期望的。

  • 您正在施放p指针dword在增加其值时。 dword是一个32位整数,因此,只有在将您的应用程序编译为32位可执行文件时,铸件才能正常工作,该应用程序在运行时使用32位内存地址。但是在64位可执行文件中,您可能会截断指向指向的内存地址。您需要使用dword_ptr(或等效)。

现在,同样,尝试更多类似的东西:

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;

I see a number of problems with this code.

  • Your use of pointer(dwProcessId) in the 2nd parameter of GetWindowThreadProcessId() is wrong. It will not work as expected at runtime. You are passing an invalid memory address for the API to write to, leading to undefined behavior. You need to use @dwProcessId instead.

  • Your use of @PB in the 3rd parameter of ReadProcessMemory() is wrong. You are reading 1 byte from the remote process into a Pointer variable, and then you are truncating that Pointer into a Byte. Although this will behave as expected at runtime, it is logically wrong, you really should use @B instead and get rid of PB altogether.

  • Your use of C in the 5th parameter of ReadProcessMemory() is wrong. This is the cause of your compiler error. In the Win32 API, that parameter expects a pointer to a SIZE_T (which is a pointer-sized unsigned integer), not the value of a Cardinal (which is a fixed-sized 32bit unsigned integer). In Delphi's Winapi.Windows unit, that parameter is declared as a var reference to a SIZE_T variable, not a var reference to a Cardinal variable, hence why you are getting the compiler error. You must declare your variable the exact same data type that the var reference is expecting.

  • The remote data in question is clearly an 8bit null-terminated ANSI string, but you are appending the 8bit characters as-is to a 16bit UnicodeString. Unless the characters in question are purely ASCII, the result will not be what you are expecting.

  • You are casting your P pointer to a Dword when incrementing its value. Dword is a 32bit integer, so that cast will only work correctly if your app is compiled as a 32bit executable, which uses 32bit memory addresses at runtime. But in a 64bit executable, you risk truncating the memory address that the pointer is pointing at. You would need to use DWORD_PTR (or equivalent) instead.

Now, with all of that said, try something more like this instead:

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文