WaitForMultipleObjects 有效,MsgWaitForMultipleObjects 失败 - 为什么?

WaitForMultipleObjects works, MsgWaitForMultipleObjects fails - why?

以下代码最低限度地演示了该问题。在后台线程中,我创建了一个有效的句柄数组并将其传递给 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);