Delphi 10.4编译器错误:“实际和形式参数的类型必须相同”
我是编程的新手。我正在使用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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我看到了此代码的许多问题。
您使用
指针(dwprocessid)
在getWindowThreadProcessid()
的第二个参数中是错误的。 在运行时不会按预期工作。您正在传递一个无效的内存地址,供API写入,导致不确定的行为。您需要使用@dwprocessid
而不是。在
readProcessMemory()
的第三参数中,您使用@pb
是错误的。您正在将远程过程中的1个字节读取到指针
变量中,然后您将指针
截断为byte
。尽管此将按照运行时的预期表现,但它是逻辑上错误的,您确实应该使用@b
,然后摆脱pb
完全。在
readprocessMemory()
的第5个参数中使用c
是错误的。这是您编译器错误的原因。在Win32 API中,该参数期望 pointersize_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
(或等效)。现在,同样,尝试更多类似的东西:
I see a number of problems with this code.
Your use of
pointer(dwProcessId)
in the 2nd parameter ofGetWindowThreadProcessId()
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 ofReadProcessMemory()
is wrong. You are reading 1 byte from the remote process into aPointer
variable, and then you are truncating thatPointer
into aByte
. Although this will behave as expected at runtime, it is logically wrong, you really should use@B
instead and get rid ofPB
altogether.Your use of
C
in the 5th parameter ofReadProcessMemory()
is wrong. This is the cause of your compiler error. In the Win32 API, that parameter expects a pointer to aSIZE_T
(which is a pointer-sized unsigned integer), not the value of aCardinal
(which is a fixed-sized 32bit unsigned integer). In Delphi'sWinapi.Windows
unit, that parameter is declared as avar
reference to aSIZE_T
variable, not avar
reference to aCardinal
variable, hence why you are getting the compiler error. You must declare your variable the exact same data type that thevar
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 aDword
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 useDWORD_PTR
(or equivalent) instead.Now, with all of that said, try something more like this instead: