Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Double-Pointer als Int-Parameter übergeben und zurück (https://www.delphipraxis.net/148190-double-pointer-als-int-parameter-uebergeben-und-zurueck.html)

Blup 25. Feb 2010 08:43

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
himitsu hat seinen Beitrag mehrmals bearbeitet, deshalb wohl der Unterschied.
Zitat:

Zitat von adk
Bei der Rückkonvertierung wird der IntWert wieder in einen Double-Zeiger konvertiert und anschliessend der Wert ausgelesen. Habe ich vielleicht noch etwas vergessen?

Ja, du hast vergessen uns nun deinen Code zu zeigen.

himitsu 25. Feb 2010 08:49

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
Was jetzt noch sein kann, ist ein Rundungsfehler

Delphi-Quellcode:
procedure ProcedureB(intWert: integer);
var
  Gewicht: double;
begin
  Gewicht := PDouble(intWert)^;
  ShowMessage(FloatToStr(Gewicht));
end;

procedure ProcedureA(Gewicht : double);
begin
  ShowMessage(FloatToStr(Gewicht));
  ProcedureB(Integer(@Gewicht))
end;
Die beiden Messageboxen sollten das Selbe anzeigen.

Speicher reservieren, über New oder Dergleichen, brauchst du eigentlich nur, wenn der Speicherplatz, wo diese Variable liegt, eventuell nicht mehr existieren könnte, wenn der Zeiger dereferenziert wird.

Hier ist es aber so, daß die ursprüngliche Variable (der Parameter "Gewicht") erst nach dem Aufruf von ProcedureB freigegeben wird und somit innerhalb der ProcedureB immer zur Verfügung stehen wird, darum reicht uch ein einfacher Zeiger (egal ob direkt oder z.B. als konvertierter Integer übergeben).

adk 25. Feb 2010 08:54

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
Das ist der fast komplette Code gewesen, lediglich die Proceduren sind umbenannt und Parameter gekürzt. Was gekürzt wurde ist in ProcedureA, in der folgendes aufgerufen wird (anstelle ProcedureB):

Delphi-Quellcode:
procedure ProcedureA(Gewicht : double)
begin
  PostThreadMessage(MyThreadId, WM_Gewichtserfassung, intAndererwert, Integer(@Gewicht));
end;
Im Thread selbst wird dann entsprechender Parameter verarbeitet:

Delphi-Quellcode:
procedure TScheduleThread.Execute;
var
  Gewicht: double
begin
  Gewicht := PDouble(Gewichtsparameter)^;
end;
Der 'Gewichtsparameter' stimmt mit dem übergebenen Wert aus ProcedureA überein. Geht da bzgl. Threads evtl. etwas verloren?

himitsu 25. Feb 2010 09:11

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
Ja, das ist was ganz Anderes.

Hier wird zwar eine Funktion aufgerufen, aber dann Zeitversetzt in einer anderen Funktion weitergearbeitet.

So würde ja der Speicher, auf welchen der Pointer zeigt schon freigegeben, bevor die andere Prozedur diesen auslesen kann.

Also hier wird dann natürlich ein Zwischenspeicher benötigt.

Delphi-Quellcode:
procedure ProcedureA(Gewicht : double)
var
  pGewicht: PDouble;
begin
  New(pGewicht);
  pGewicht := @Gewicht;
  PostThreadMessage(MyThreadId, WM_Gewichtserfassung, intAndererwert, Integer(pGewicht));
end;

procedure TScheduleThread.Execute;
var
  Gewicht: double
begin
  Gewicht := PDouble(Gewichtsparameter)^;
  Dispose(PDouble(Gewichtsparameter)); // das Freigeben nicht vergessen

  ShowMessage(FloatToStr(Gewicht));
end;
[edit] @ und p eingefügt ... siehe #15

adk 25. Feb 2010 09:51

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
Zitat:

Zitat von himitsu
Delphi-Quellcode:
procedure ProcedureA(Gewicht : double)
var
  pGewicht: PDouble;
begin
  New(pGewicht);
  pGewicht := Gewicht;
  PostThreadMessage(MyThreadId, WM_Gewichtserfassung, intAndererwert, Integer(Gewicht));
end;

procedure TScheduleThread.Execute;
var
  Gewicht: double
begin
  Gewicht := PDouble(Gewichtsparameter)^;
  Dispose(PDouble(Gewichtsparameter)); // das Freigeben nicht vergessen

  ShowMessage(FloatToStr(Gewicht));
end;

Das schaut gut aus, aber: Sind folgende Korrekturen korrekt? (@ und 'p' hattest du vergessen):

Delphi-Quellcode:
procedure ProcedureA(Gewicht : double)
var
  pGewicht: PDouble;
begin
  New(pGewicht);
  pGewicht := @Gewicht;
  PostThreadMessage(MyThreadId, WM_Gewichtserfassung, intAndererwert, Integer(pGewicht));
end;
Wenn ja, habe ich leider dasselbe Problem wie vorher.

himitsu 25. Feb 2010 09:57

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
Jupp, glatt vergessen, aber im Prinzip müßte es so jetzt funktionieren. :gruebel:


Schau mal, ob Gewichtsparameter nach dem Empfangen den selben Wert hat, wie Integer(pGewicht) vor dem Versenden.

adk 25. Feb 2010 10:06

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
Hatte ich schon. Ja, hat er.

Ich glaube ich habe euch jetzt schon überstrapaziert, werde das evtl. mit globalen Variablen lösen. Sollte es noch anders gehen, werde ich die Lösung hier noch reinstellen.

himitsu 25. Feb 2010 10:13

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
Dann sollte es auch funktionieren.

Es sei denn du hast irgendwo noch einen Bufferoverrun.


Oder es liegt wirklich nur an einem Rundungs-/Anzeigefehler, wo oftmals kleinere Abweichungen normal sind.

adk 2. Mär 2010 12:00

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
Die Lösung:

Es wird ein seperater Typ angelegt, also eine Klasse, die einen Double-Wert enthält. Von diesem Typ wird eine Instanz in ProcedureA angelegt und der Double mit einem Wert belegt. Anschliessend wird ein Longint(Instanz) als Parameter an ProcedureB weitergeben. In ProcedureB kann dieser wieder in den alten Typ konvertiert werden, die Instanz existiert ja auch noch im Speicher. Allerdings muss diese Instanz dann explizit wieder freigegeben werden.

Also keine (direkte) Verwendung von Zeigern. Wusste nicht das so etwas geht in Delphi. Wie nennt man das/dieses Prinzip?

himitsu 2. Mär 2010 12:17

Re: Double-Pointer als Int-Parameter übergeben und zurück
 
PS: eine Objekinstanz ist auch nur ein Zeiger auf die Objektdaten.

Ein Objekt ist praktisch ein Zeiger auf einen "Record" mit 'ner rießigen Klassenverwaltung und 'ner Menge zusätzlicher RTTI-Daten.

Und ja, sowas geht und wird in der VCL an einigen Stellen auch so gemacht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:04 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz