AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Parameterübergabe bei CreateThread
Thema durchsuchen
Ansicht
Themen-Optionen

Parameterübergabe bei CreateThread

Ein Thema von SebE · begonnen am 20. Mai 2007 · letzter Beitrag vom 20. Mai 2007
Antwort Antwort
SebE

Registriert seit: 31. Jul 2004
Ort: Chemnitz
316 Beiträge
 
Delphi 7 Personal
 
#1

Parameterübergabe bei CreateThread

  Alt 20. Mai 2007, 10:18
Ich habe ein Objekt, welches einen Thread starten soll.
Delphi-Quellcode:
...
protected
  procedure _run(const t: pointer); stdcall;
public
    fRunProc: OBJPROC;
...
Typen sind folgendermaßen deklariert:
Delphi-Quellcode:
type
  PROC = procedure;
  OBJPROC = procedure(const t: pointer) of object; stdcall;
Konstruktor des Objekts:
Delphi-Quellcode:
constructor <Objektname>._create(myProc: PROC);
begin
inherited Create;

fRunProc := _run;
fProc := @myProc;
Aufruf des Threads:

Delphi-Quellcode:
var
  i: DWORD;
begin
i := 5;

fMainThread := CreateThread(nil, 0, @fRunProc, @i, 0, fMainThreadID) //Übergebe ich "i" richtig?
...
Meine "Thread-Routine":
Delphi-Quellcode:
procedure <Objektname>._run(const t: pointer);
var
  thread: DWORD;
  threadID: DWORD;
begin
writeln('>>', DWORD(t), '<<'); //<-- es wird "0" ausgegeben!

...
end;
Wie komme ich an den "richtigen" Wert (5)?
Sebastian
  Mit Zitat antworten Zitat
Basilikum

Registriert seit: 9. Aug 2003
389 Beiträge
 
Delphi 7 Professional
 
#2

Re: Parameterübergabe bei CreateThread

  Alt 20. Mai 2007, 11:38
Zitat von SebE:
Aufruf des Threads:

Delphi-Quellcode:
var
  i: DWORD;
begin
i := 5;

fMainThread := CreateThread(nil, 0, @fRunProc, @i, 0, fMainThreadID) //Übergebe ich "i" richtig?
...
i wird theoretisch richtig übergeben - allerdings gibt es da ein Problem: i liegt auf dem Stack, dieser wird jedoch beim Verlassen der Funktion wieder abgeräumt und der Speicherbereich anderweitig wieder verwendet - sprich: der Wert von i kann sich dadurch verändern, bzw. zum Zeitpunkt des Anlaufens vom Thread ist nicht garantiert, dass i noch so ist, wie es zum Zeitpunkt von CreateThread war..... besser also: für i auf dem Heap Speicher allozieren, und diesen Pointer an den Thread übergeben, welcher dann nach Gebrauch den Speicher wieder freigibt (var i : pdword; begin new(i); i^:=5; ..... dispose(i); )
weiter verträgt sich ein API-Call nicht mit Object-Procedure-Pointer (Procedure of Object)... diese enthalten implizit das "Self", welches beim Start der Funktion in das Register EAX geladen werden müsste - das wird Windows mit Garantie nicht machen...
Du musst also noch eine Wrapper-Schicht mehr einbauen - ein Thread, welcher als Parameter den Parameter (@i) und die gewünschte Methode (@fRunProc) z.B. als Record entgegen nimmt...

Zitat von SebE:
Meine "Thread-Routine":
Delphi-Quellcode:
procedure <Objektname>._run(const t: pointer);
var
  thread: DWORD;
  threadID: DWORD;
begin
writeln('>>', DWORD(t), '<<'); //<-- es wird "0" ausgegeben!

...
end;
sie oben, plus: mit DWORD(t) greifst du auf die Adresse des Pointers zu, nicht auf den Speicher, auf den er zeigt... richtig dereferenziert wird mit: PDWORD(t)^ oder auch DWORD(t^)
  Mit Zitat antworten Zitat
SebE

Registriert seit: 31. Jul 2004
Ort: Chemnitz
316 Beiträge
 
Delphi 7 Personal
 
#3

Re: Parameterübergabe bei CreateThread

  Alt 20. Mai 2007, 14:33
@Basilikum: Danke für deine Antwort.
Zitat:
sie oben, plus: mit DWORD(t) greifst du auf die Adresse des Pointers zu, nicht auf den Speicher, auf den er zeigt... richtig dereferenziert wird mit: PDWORD(t)^ oder auch DWORD(t^)
Is mir schon klar, das war ein Überbleibsel vom Testen, da die Adresse bekannt war, wollte ich sie mir NACH der Übergabe anzeigen lassen.

Ich schreib mal, was ich geändert hab, damit es der Eine oder Andere verwenden kann, der das gleiche Problem hat:
Delphi-Quellcode:
procedure _run(const param: pointer); stdcall;
var
  t: <Objektname>;
  threadID: DWORD;
begin
t := <Objektname>(PDWORD(param^));

//Hier wird mit t gearbeitet (was übergeben wurde)
...
end;
Delphi-Quellcode:
procedure <Objektname>._start;
begin
...

fMainThread := CreateThread(nil, 0, @_run, @DWORD(Self), 0, fMainThreadID) //Änderung! Jetzt läuft's :-)
end;

procedure <Objektname>._stop;
begin
...

TerminateThread(fMainThreadID, 0)
end;
Wie man sieht, funktioniert es auch ohne New/Dispose - war aber trotzdem ein guter Gedanke.
Sebastian
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz