J..*_*... 3 delphi winapi multithreading delphi-10-seattle
以下代码最低限度地演示了该问题.在后台线程中,我创建一个有效的句柄数组并将其传递给,WaitForMultipleObjects并成功等待对象.
MsgWaitForMultipleObjects但是,当传递完全相同的数组时,函数调用failed(WAIT_FAILED)with ERROR_INVALID_HANDLE.
我究竟做错了什么?
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows, SyncObjs, Classes;
type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;
procedure TMyThread.Execute;
var
LEvent : TEvent;
LWaitHandles : TWOHandleArray;
LPWaitHandles : PWOHandleArray;
LWaitResult : Cardinal;
begin
LEvent := TEvent.Create;
LWaitHandles[0] := LEvent.Handle;
LPWaitHandles := @LWaitHandles;
while not Terminated do begin
{Works -> LWaitResult := WaitForMultipleObjects(1, LPWaitHandles, false, INFINITE);}
{Fails ->} LWaitResult := MsgWaitForMultipleObjects(1, LPWaitHandles, false, INFINITE, QS_ALLINPUT);
case LWaitResult of
WAIT_OBJECT_0: WriteLn('Event 1 Signaled');
{ etc... }
WAIT_FAILED : WriteLn(SysErrorMessage(GetLastError));
end;
end;
end;
var
lt : TMyThread;
begin
lt := TMyThread.Create(false);
ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)
虽然handle参数的WinAPI签名对于这两个调用是相同的:
_In_ const HANDLE *pHandles,
Run Code Online (Sandbox Code Playgroud)
然而,RTL以不同的方式包含这些功能. WaitForMultipleObjects使用指针类型:
lpHandles: PWOHandleArray;
Run Code Online (Sandbox Code Playgroud)
while MsgWaitForMultipleObjects使用无类型var参数:
var pHandles;
Run Code Online (Sandbox Code Playgroud)
因此必须将句柄数组直接传递给MsgWaitForMultipleObjects.
即:
LWaitResult := MsgWaitForMultipleObjects(1, LWaitHandles, false, INFINITE, QS_ALLINPUT);
Run Code Online (Sandbox Code Playgroud)