Autor Beitrag
alias5000
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: Di 05.06.07 15:54 
Hi!
Ich habe ein seltsames Problem.

Das Problem ist folgendes:
Ich packe in ein Objekt einen String rein, reiche den über 5 Ecken weiter und bekomme dann später einen anderen String da rein. Und dazu einen ganz seltsamen.
Der Hintergrund ist folgender:
Ich habe mir eine Komponente geschrieben, die mir mein selbst definiertes Textformatierungsformat in HTML umwandelt.
Da das Umwandeln in einem Thread passiert, wird das Programm über ein Event benachrichtigt, wenn das Umwandeln fertig ist. Es müssen aber Informationen weitergegeben werden, zwischen der Methode, die das Umwandeln anstößt und dem Zeitpunkt, an dem das Umwandeln fertig ist. Das sollen beliebige Daten sein (die Anwendung soll den Typ bestimmen können), daher ist das einfach ein Pointer.

Wenn die Anwendung das Umwandeln anstößt, passiert folgendes:


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
    info := THTMLConvInfo.Create;
    info.Log := log;
    info.HTMLSource := Source;
    info.AdditionalText := PChar(GlobalSettings.TextConv.FormatStringToHTML(Utils.GetLogMessageBegin(User), Font) + '<br>%%&&MESSAGETEXT&&%%<br>');
    info.ReplacePattern := PChar('%%&&MESSAGETEXT&&%%');
    GlobalSettings.TextConv.ParseToHTML(Text, info); //-->ParseToHTML(Text: string; Data: Pointer);

info ist vom Typ THTMLConvInfo, der wie folgt definiert ist und das Konstrukt ist, dass die Anwendungsspezifischen Daten enthält:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  THTMLConvInfo = class
    Log: THTMLViewer;
    HTMLSource: TStringList;
    AdditionalText: PChar;
    ReplacePattern: PChar;
  end;


In der Komponente, die nach HTML umwandelt (zu ihr gehört die Methode ParseToHTML) wird ein Thread erstellt (Ableitung von TThread), in dessen Konstruktor der Pointer "Data" einfach weitergegeben wird und in einer Variable im Thread-Objekt gespeichert ist.
Die Execute-Methode des Threads sieht so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
  ConvertToRealHTML(fInput, fOutput, fParserOffset); //hier wird im Thread tatsächlich konvertiert. Das Ergebnis ist fOutput

//anschließend wird per Event das Ergebnis weitergegeben



Durch Debuggen habe ich rausgefunden, dass sich der PChar AdditionalInfo in dem Objekt THTMLConvInfo mal in einen anderen ändert (obwohl er nicht sollte), oder auch nicht.
Beim Debuggen bin ich darauf gestoßen, dass an dieser Codestelle der PChar AdditionalText (das Objekt dazu ist ja im allgemeinen Pointer "Data" des Thread Objekts gespeichert) in den Text "Output" ändert und dies dann später auch in der Hauptanwendung so ankommt.
Die Codestelle ist ein schlichtes insert:
ausblenden Delphi-Quelltext
1:
2:
   
      Insert(newtag, Output, CurrentPosition);

Output ist wie gesagt ein string, dessen Wert mein AdditionalText auch übernimmt, aber halt nur manchmal. Output ist schon in der Deklaration der Methode ConvertToRealHTML deklariert. Der Rest sind nur lokale Variablen, die sich aus dem Kontext ergeben sollten.

Jetzt hatte ich vermutet, dass die Informationen, auf die der Pointer zeigt, einfach verloren gehen. Dann habe ich aber mal den Pointer zu Testzwecken durch das ersetzt, was ich da in meinem Fall reinlade, nämlich eine Instanz von THTMLConvInfo. Das Ergebnis ist leider immernoch dasselbe :cry:

Gruß
alias5000

Posting nochmal komplett überarbeitet, um das Problem etwas klarer darzustellen

Edit2: Letzten Absatz verändert

_________________
Programmers never die, they just GOSUB without RETURN


Zuletzt bearbeitet von alias5000 am Mi 06.06.07 11:30, insgesamt 2-mal bearbeitet
alias5000 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: Di 05.06.07 16:17 
Dank user profile iconGTA-Place's Hinweis hat sich rausgestellt, dass vor dem PostMessage der String auch schon nimmer stimmt.

Gruß
alias5000


Edit: durch das editierte Post oben verliert dieser Post seinen Sinn

_________________
Programmers never die, they just GOSUB without RETURN


Zuletzt bearbeitet von alias5000 am Mi 06.06.07 11:19, insgesamt 1-mal bearbeitet
alias5000 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: Mi 06.06.07 00:54 
Die Sache wird nun etwas seltsam für mich.
Ich hab dem ganzen mal hinterherdebuggt, mit folgendem Ergebnis:
Der Wert ändert sich in der Routine ConvertToRealHTML, die im Thread ausgeführt wird und letztendlich den Input in meinem Format in den Output in HTML-Formatierung umwandelt.
Die Routine ist, zur Erinnerung, wiefolgt deklariert:
ausblenden Delphi-Quelltext
1:
procedure TLC2HTMLParserThread.ConvertToRealHTML(Input: stringvar Output: string; Offset: integer);					

Die Variable fData (Typ Pointer), in der der String steckt, der sich verändert, wird in der gesamten Routine nicht ein einzigstes mal angefasst.
Wenn ich folgende Anweisung ausführe, ändert sich häufiger der String in den String, der in der Variable "Output" (im folgenden Quelltext) steckt:
ausblenden Delphi-Quelltext
1:
      Insert(newtag, Output, CurrentPosition);					

newtag ist vom Typ string und schlichtweg der HTML-Tag, der in den String als neuer eingefügt werden soll, Output dann natürlich der String, in den alles geht (das ist die Variable, die im header der Routine ConvertToRealHTML deklariert ist) und CurrentPoisition ist ja klar, denk ich mal.

Da fData ein Pointer ist, kann das sein, dass durch ein insert im Speiher irgendwas verschoben wird???
Ich steh grad gewaltig auf dem SChlauch...

gruß
alias5000

Edit: das habe ich auch in den ersten Post mit eingearbeitet

_________________
Programmers never die, they just GOSUB without RETURN


Zuletzt bearbeitet von alias5000 am Mi 06.06.07 11:20, insgesamt 1-mal bearbeitet
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 06.06.07 01:18 
Moin!

Ich gebe zu, ich blicke auf Anhieb nicht voll durch, was du da im Detail tust, aber ich gebe mal folgendes zu bedenken, da du ja auch schon selbst auf die Pointer-Zusammenhänge verwiesen hast:

Wenn du (lange Delphi-)Strings durch Pointer "weiterreichst", dann hängst du AFAIK die Compiler-Magic ab, die an den Strings "hängt". :idea:

Vielleicht kann user profile iconBenBE dazu bessere "Auskünfte" geben, ich stecke nicht soo tief im Compiler... :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
alias5000 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: Mi 06.06.07 01:50 
Das du da nicht genau durchblickst, versteh ich, iss ja auch recht langatmig beschrieben. Morgen editier ich vllcht den Beitrag nochmal zusammen, weil ich das Problem ja jetzt eingrenzen konnte.

Ich sprech Benny morgen mal an, ob er was weiß :idea:

Dass er die Strings evtl. "verliert" hate ich auch schon überlegt (nur als Spekulation) und hatte daraufhin (ohne zu wissen, ob das konkret was ändert) auf PChar umgeschwenkt. Auch wenn ich "Data" als TObject, statt Pointer weitergebe, ändert sich nichts am Verhalten (was ich auch nicht ernsthaft erwarte) :cry:

_________________
Programmers never die, they just GOSUB without RETURN
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 06.06.07 06:44 
Wieso verwendest Du überhaupt Windows-Botschaften? Deklariere Dir einfach ein Event 'OnAfterConvert':
ausblenden Delphi-Quelltext
1:
TAfterConvertEvent = Procedure (Sender : TObject; Const anOutput, aData : String);					

Und ParseToHTML erhält einen weiteren Parameter, nämlich die Callback-Routine.

So wäre das sauber in imho spricht nichts dagegen, daß das dann sauber funktioniert.

Neben den erwähnten Problemen mit den String-Referenzzählern könnte ich mir auch noch vorstellen, das der Thread gar nicht mehr lebt, wenn die Windows-Botschaft abgearbeitet wird: Schließlich arbeitest Du mit PostMessage, und da weiss man ja nie, wann die Message verdaut wird.

_________________
Na denn, dann. Bis dann, denn.
alias5000 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: Mi 06.06.07 10:59 
Das mit den Windows Botschaften habe ich rausgenommen, auch weil sich damit nichts an dem eigentlichen Problem ändert. Das tritt im Thread selbst schon auf (beschrieben im Post vor dem von Narses).
Gruß
alias5000

Edit: So ich habe jetzt wie versprochen das erste Posting so editiert, dass die eigentliche Problemstelle hoffentlich etwas klarer wird

Edit2: ich habe oben noch etwas neues hinzugefügt (dass ich mal den Pointer durch das konkrete THTMLConvInfo ersetzt habe)

_________________
Programmers never die, they just GOSUB without RETURN
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 06.06.07 11:29 
Ah, sorry. Mein Tip: Alle PCHAR raus, und statt dessen String rein. Denn Insert verschiebt natürlich Speicher und den ganzen String auch... Wenn Du mit Strings arbeitest, musst du dich damit nicht rumschlagen...

_________________
Na denn, dann. Bis dann, denn.
alias5000 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: Mi 06.06.07 11:36 
user defined image
Woooohooooo
Das wars :D
Ich weiß jetzt nimmer, warum ich da PChars eingesetzt habe (den Grund habe ich glaub ich inzwischen eh aus der Source rauseditiert), aber jetzt funktioniert es einwandfrei :D

Vielen Dank
alias5000

_________________
Programmers never die, they just GOSUB without RETURN