AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Parameterübergabe bei BeginThread für Klassenmethode
Thema durchsuchen
Ansicht
Themen-Optionen

Parameterübergabe bei BeginThread für Klassenmethode

Ein Thema von s.h.a.r.k · begonnen am 2. Jul 2010 · letzter Beitrag vom 5. Jul 2010
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#1

Parameterübergabe bei BeginThread für Klassenmethode

  Alt 2. Jul 2010, 01:34
Ich habe im Moment eine threoretische Fragen, bei der ich nicht ganz verstehe, warum es denn nicht klappt. Und zwar kann ich via BeginThread() ja den Code einer Procedure als Thread ausführen -- das ganze klappt auch wunderbar mit einer Klassenmethode. Nun wollte ich auf Self als Parameter übergeben, was ich auch via [delphi]Pointer(Self)[/delphi) getan habe.

Wenn ich nun eine Klassenmethode via BeginThread ausführe, so bekomme ich es nicht gebacken, Self über den Parameter zu erhalten. Habe ich statt dessen eine (globale) Procedure als Thread-Code, so funktioniert die Übergabe von Self ohne Probleme. Nur warum ist das so? Ich habe in einem Post vorher gelesen, dass das nur so klappt, nur stand da leider keinerlei Begründung.

Hier nochmal etwas Code:
Delphi-Quellcode:
type
TTest = class(TObject)
private
  FThreadHandle : Integer;
  FThreadID : Cardinal;
public
  procedure StartIt();
  procedure ThreadedMethod(Instance: TTest);
end;

procedure ThreadedProcedure(Instance: TTest);

implementation

// --- here the global procedure ---
procedure ThreadedProcedure(Instance: TTest);
begin
  //
  // < ------- Instance = Self parameter
  //
end;

// --- here the class methods ---
procedure TTest.StartIt();
begin
  // i know, i overwrite the handle and id ;)
  FThreadHandle := BeginThread(nil, 0, @ThreadedProcedure, Pointer(Self), 0, FThreadID);
  FThreadHandle := BeginThread(nil, 0, @TTest.ThreadedMethod, Pointer(Self), 0, FThreadID);
end;

procedure TTest.ThreadedMethod(Instance: TTest);
begin
  //
  // < ------- Instance <> Self parameter
  //
end;
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

AW: Parameterübergabe bei BeginThread für Klassenmethode

  Alt 2. Jul 2010, 07:48
Das ist ganz einfach.
Deine Methode TTest.ThreadedMethod sieht intern so aus:
procedure TTest.ThreadedMethod(Self: TTest; Instance: TTest); Es gibt also immer als ersten Parameter den unsichtbaren Self-Parameter. Anders ausgedrückt heißt es das deine Methode incompatibel zur erwarteten Funktion ist die eben nur einen Parameter vom Typ Pointer hat. Man sollte sich aber auch nicht darauf verlassen das es in alle Ewigkeit so aussieht das der erste unsichtbare Parameter Self ist. Denn wenn irgendwann mal in einer neuen Version oder bei einem anderen Compiler das ganze intern anders gehandhabt wird funktionieren dann solche hacks nicht mehr:
procedure TTest.ThreadedMethod(); (also das man eine Parameterlose Methode nimmt wohlwissen das der unsichtbare Parameter Self der einzige ist.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's

Geändert von SirThornberry ( 2. Jul 2010 um 07:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.115 Beiträge
 
Delphi 12 Athens
 
#3

AW: Parameterübergabe bei BeginThread für Klassenmethode

  Alt 2. Jul 2010, 07:57
oder als statische Klassenmethode:
class procedure ThreadedMethod(Instance: TTest); static; .

Methoden und "nicht-statische" Klassen-Methoden haben eben dieses unsichtbare "Self" mit drin.
> Methode: Self=Objektinstanz
> Klassen-Methode: Self=Klassen-Typ
> statische (static) Klassen-Methode: Self gibt's nicht
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#4

AW: Parameterübergabe bei BeginThread für Klassenmethode

  Alt 2. Jul 2010, 08:06
@himitsu? Bist du sicher das es so funktioniert? Ich hab mir den ASM-Code nicht angesehen aber kann es nicht sein das auch bei Klassenmethoden der unsichtbare Self-Parameter existiert? Nur eben nicht als Instanz sondern der Klasse selbst.

[Edit]
@himitus: Hätte ich deinen Beitrag mal zu Ende gelesen so hätte ich mir diesen Beitrag im gesamten hier sparen können
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Parameterübergabe bei BeginThread für Klassenmethode

  Alt 2. Jul 2010, 08:07
@SirThornberry:
Hat er doch geschrieben?!
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#6

AW: Parameterübergabe bei BeginThread für Klassenmethode

  Alt 2. Jul 2010, 15:51
Das ist ganz einfach.
Deine Methode TTest.ThreadedMethod sieht intern so aus:
procedure TTest.ThreadedMethod(Self: TTest; Instance: TTest); Es gibt also immer als ersten Parameter den unsichtbaren Self-Parameter. Anders ausgedrückt heißt es das deine Methode incompatibel zur erwarteten Funktion ist die eben nur einen Parameter vom Typ Pointer hat. Man sollte sich aber auch nicht darauf verlassen das es in alle Ewigkeit so aussieht das der erste unsichtbare Parameter Self ist. Denn wenn irgendwann mal in einer neuen Version oder bei einem anderen Compiler das ganze intern anders gehandhabt wird funktionieren dann solche hacks nicht mehr:
procedure TTest.ThreadedMethod(); (also das man eine Parameterlose Methode nimmt wohlwissen das der unsichtbare Parameter Self der einzige ist.
Gehe ich richtig in der Annahme, dass, mit aktuellem Compiler, es mit einer Methode ohne Parameter funktioniert?!
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.115 Beiträge
 
Delphi 12 Athens
 
#7

AW: Parameterübergabe bei BeginThread für Klassenmethode

  Alt 2. Jul 2010, 16:03
Das ist bei Delphi eigentlich schon immer so, also daß Klassen-Methoden diesen unsichtbaren Parameter haben.
Irgendwo muß je die Information herkommen, um welche Klasse/Instanz es sich handelt, wenn man eine Methode aufruft.

Der TMethod-Zeiger ist auch um diesen Parameter größer.
(Zeiger auf Methode + die Objektinstanz)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#8

AW: Parameterübergabe bei BeginThread für Klassenmethode

  Alt 2. Jul 2010, 16:16
Nur habe ich diese Information immer nur aus dem DP-Forum. An offizieller Stelle habe ich das noch nie gesehen.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.115 Beiträge
 
Delphi 12 Athens
 
#9

AW: Parameterübergabe bei BeginThread für Klassenmethode

  Alt 2. Jul 2010, 18:37
Offiziell steh halt einiges nirgends.

z.B. sieht
function test: String; intern eigentlich so aus
procedure test(var Result: String); Bei einem Integer sieht es aber anders aus.


Ihr könnt ja gerne mal raten, welche Werte von den Messageboxen angezeigt werden ... mal sehn wer alles richtig tippt.
Delphi-Quellcode:
function Test: String;
begin
  Result := Result + 'abc ';
  raise Exception.Create('buhh');
end;

function Test2: String;
begin
  Result := Result + 'abc ';
end;

function Test3: Integer;
begin
  Result := 1;
  raise Exception.Create('buhh');
end;

function Test4: Integer;
begin
  Result := Result + 1;
end;

procedure TForm1.FormCreate(Sender: TObject);
var S: String;
  i: Integer;
begin
  try
    S := Test;
  except
    // heut ma nix
  end;
  ShowMessage(S);
  S := 'tja ';
  S := Test2;
  S := Test2;
  ShowMessage(S);

  try
    i := Test3;
  except
    // heut ma nix
  end;
  ShowMessage(IntToStr(i));
  i := 10;
  i := Test4;
  i := Test4;
  ShowMessage(IntToStr(i));
end;
PS: Das ist auch ein gutes Beispiel, warum meistens Variablenwerte immer initialisiert werden sollten.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#10

AW: Parameterübergabe bei BeginThread für Klassenmethode

  Alt 3. Jul 2010, 10:48
...Ihr könnt ja gerne mal raten, welche Werte von den Messageboxen angezeigt werden ...
Der Vollständigkeit halber wäre es schön wenn du uns verraten könntest was bei dir angezeigt wird. Denn wenn in 20 Jahren niemand mehr das gleiche Delphi hat wie jenes welches du derzeit benutzt, kann man nur raten ob es in deren Versionen das gleiche ergibt wie bei dir jetzt.

Wie sieht es eigentlich mit der Aufrufkonvention aus? Ist BeginThread eine Api-Funktion? Wenn ja wird doch sicher stdcall oder cdecl erwartet oder?
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's

Geändert von SirThornberry ( 3. Jul 2010 um 10:50 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 12:57 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