2011-02-24 62 views
3

我有傳遞類引用作爲參數傳遞給ThreadProc的中的CreateThread調用的問題。下面是一個說明我有這個問題的一個範例程序:將參數傳遞給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我期待。

這可能是德爾福是如何工作的只是一個基本的誤解,所以可能有人請告訴我如何得到這個工作正常?

回答

9

這裏的問題是,你的線程函數有錯誤的調用約定。你需要與stdcall約定聲明它:

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

enter image description here


話雖如此,這將是更地道只使用一個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,而不是一個適當的類型化的函數指針?

+3

'b.fe:= 42;',不要忘了':':) – Kokonotsu 2011-02-24 21:04:59

+2

@Kokonotsu任何特別是不要使用'TThread'原因是什麼?至於'='和':=',猜猜我今天做了太多的P/Invoke! – 2011-02-24 21:06:29

+0

很多打字,以及*截圖* ...快你是誰! – 2011-02-24 21:09:30

9

你忘了stdcall指令。

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

並且不要在使用Pointer鑄造:

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

b已經是一個Pointer(一個Class,這是一個ObjectPointer