MsgWaitForMultipleObjects

MsgWaitForMultipleObjects

下面的代码最少地演示了该问题。在后台线程中,我创建了一个有效的句柄数组并将其传递给WaitForMultipleObjects,这成功地等待了对象。

但是,将完全相同的数组传递给MsgWaitForMultipleObjects时,使用WAIT_FAILED的函数调用失败(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.

最佳答案

尽管这两个调用的handles参数的WinAPI签名是相同的:

 _In_ const HANDLE *pHandles,


但是,RTL以不同的方式包装这些功能。 WaitForMultipleObjects使用指针类型:

lpHandles: PWOHandleArray;


MsgWaitForMultipleObjects使用无类型的var参数:

var pHandles;


因此,必须将句柄数组直接传递给MsgWaitForMultipleObjects

即:

LWaitResult := MsgWaitForMultipleObjects(1, LWaitHandles, false, INFINITE, QS_ALLINPUT);

08-25 21:24