Передача параметра в CreateThread - PullRequest
3 голосов
/ 24 февраля 2011

У меня проблема с передачей ссылки на класс в качестве параметра ThreadProc при вызове CreateThread. Вот пример программы, которая демонстрирует мою проблему:

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, поэтому кто-то может подсказать, как это работает правильно?

Ответы [ 3 ]

10 голосов
/ 25 февраля 2011

Проблема в том, что ваша функция потока имеет неправильное соглашение о вызовах.Вы должны объявить это с соглашением stdcall:

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

enter image description here


Сказав это, было бы более идиоматичным просто использовать потомок TThreadкоторая обрабатывает функцию ООП в С обратно к переходу ООП для вас.Это будет выглядеть так:

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 объявляет TFNThreadStartRoutine как TFarProc, а не как типичный указатель на типизированную функцию?

9 голосов
/ 25 февраля 2011

Вы забыли директиву stdcall.

function ThreadProc(param: Pointer) : DWORD; stdcall;
1 голос
/ 10 июля 2011

И не используйте Pointer приведение:

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

b уже Pointer (Class, что Object Pointer)

...