3

我在调用 CreateThread 时将类引用作为参数传递给 ThreadProc 时遇到问题。这是一个示例程序,演示了我遇到的问题:

program test;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows, Dialogs;

type
    TBlah = class
        public
        fe: Integer;
    end;

function ThreadProc(param: Pointer) : DWORD;
begin
    ShowMessage(IntToStr(TBlah(param).fe));

    Result := 0;
end;

var
    tID: DWORD;
    handle: THandle;
    b: TBlah;
begin
    b := TBlah.Create;
    b.fe := 54;

    handle := CreateThread(nil, 0, @ThreadProc, Pointer(b), 0, tID);

    WaitForSingleObject(handle, INFINITE); 
end.

调用ShowMessage弹出一个消息框,里面有类似245729105的东西,54不像我期望的那样。

这可能只是对 Delphi 工作原理的一个基本误解,所以有人可以告诉我如何让它正常工作吗?

4

3 回答 3

10

这里的问题是你的线程函数有错误的调用约定。您需要使用stdcall约定声明它:

function ThreadProc(param: Pointer) : DWORD; stdcall;

在此处输入图像描述


话虽如此,只使用一个TThread后代来处理 OOP 到 C 函数返回到 OOP 转换会更惯用。看起来像这样:

type
  TBlah = class(TThread)
  protected
    procedure Execute; override;
  public
    fe: Integer;
  end;

procedure TBlah.Execute;
begin
  ShowMessage(IntToStr(fe));
end;

var
  b: TBlah;

begin
  b := TBlah.Create(True);
  b.fe := 42;
  b.Start;
  b.WaitFor;
end.

顺便说一句,有谁知道为什么 Windows.pas 声明TFNThreadStartRoutineTFarProc而不是正确的类型化函数指针?

于 2011-02-24T21:01:27.183 回答
9

你忘记了stdcall指令。

function ThreadProc(param: Pointer) : DWORD; stdcall;
于 2011-02-24T21:00:13.840 回答
1

并且不要使用Pointercast :

handle := CreateThread(nil, 0, @ThreadProc, **Pointer**(b), 0, tID); 

b已经是一个Pointer(a Class, 这是一个Object Pointer)

于 2011-07-10T02:45:05.333 回答