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に何かがあるメッセージボックスをポップアップします。24572910554

これはおそらく、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が適切な型付き関数ポインターではなく宣言する理由TFNThreadStartRoutineを知っている人はいますか?TFarProc

于 2011-02-24T21:01:27.183 に答える
9

stdcallディレクティブを忘れています。

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

Pointerキャストインを使用しないでください:

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

bはすでにPointer(aClassであり、これは ですObject Pointer)

于 2011-07-10T02:45:05.333 に答える