AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Stringübergabe in DLL´s

Ein Thema von Christian Kaufmann · begonnen am 29. Aug 2002 · letzter Beitrag vom 30. Aug 2002
Antwort Antwort
Seite 2 von 2     12   
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#11
  Alt 30. Aug 2002, 10:49
Moin Christian,

könntest Du bitte mal den Code der Routine die den string erzeugt, und der verarbeitenden Funktion posten (incl. Aufruf derselben)?
Irgendwie kann ich mir im Moment keine Ursache für das Problem erklären.
Der Funktionsabschnitt, in der die Execpetion ausgelöst wird wäre auch nicht schlecht.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#12
  Alt 30. Aug 2002, 12:44
Kuckst du hier: http://home.t-online.de/home/PeterJH...icles/dlls.htm
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Christian Kaufmann

Registriert seit: 5. Aug 2002
7 Beiträge
 
#13
  Alt 30. Aug 2002, 12:48
Am Formular ist ein Memofeld und ein Button.


function spiegeln(p:pchar):pchar;
var
i:integer;
test1,test:string ;
begin

test:=string(p);
test1:='';
for i := length(test) downto 1 do
begin
test1:=test1+test[i];
end;
result:=pchar(test1);

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
memo1.Text:=(spiegeln(pchar(memo1.Text)));
end;
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.481 Beiträge
 
Delphi 10.1 Berlin Professional
 
#14
  Alt 30. Aug 2002, 13:19
Code:
[b]function[/b] spiegeln(p: PChar): PChar;
[b]var[/b] test: [b]string;
begin[/b]
  test := [b]string[/b](p);
  ...
  Result := PChar(test);
[b]end[/b];
Um dir mal zu erklären, warum das nicht funktioniert:

Dein Programm ruft spiegeln(PChar(MyString)) auf, dabei wird PChar(MyString) auf dem sog. Stack abgelegt und p zeigt auf die Speicherstelle im Stack, an der PChar(MyString) liegt. (Danach kommt noch die Rücksprungadresse auf den Stack.)
Nun wird Platz auf dem Stack für die lokale Variable test gemacht. In diese kopierst du den PChar, auf den p zeigt und führst deine Umkehrung durch.
Bis jetzt funktioniert alles, doch nun kommt der entscheidende logische Fehler:
Du weist Result nun einen Zeiger (PChar ist ja nur ein Zeiger) auf die Speicheradresse, an der test abgelegt ist, zu. Doch da test eine lokale Variable ist und somit auf dem Stack liegt, zeigt Result auf eine Adresse im Stack.
Durch das end; wird nun aber der von test belegte Stack-Speicher freigegeben, womit Result auf einen bereits freigegebenen Speicherbereich zeigt. Wenn nun ein weiterer Funktionsaufruf nach dem Zurückkehren der spiegeln-Funktion stattfindet (es reicht auch eine einfache Zuweisung von Variablen), dann überschreibt diese die noch auf dem Stack an der Result-"Adresse" liegenden, unveränderten Bytes mit ihren eigenen lokalen Variablen und Parametern.
Deswegen liefert die Funktion nur noch Bytesschrott zurück, der auch noch zum teilweise auch noch aus den "orignal"-Daten bestehen kann (was die Fehlersuche dann eher auf die Funktion selbst ziegt).


Das Problem könntest du z.B. so lösen, dass du den String "in-place" spiegelst (also Eingabe-Parameter = Ausgabe-Parameter):
Code:
[b]procedure[/b] spiegeln(p: PChar);
[b]var[/b] s: [b]string[/b];
[b]begin[/b]
  s := p;
  ...
  StrLCopy(p, PChar(s), StrLen(p)); // Daten in p zurückschreiben
[b]end[/b];

s := 'Dies ist ein Test';
spiegeln(PChar(s));
ShowMessage(s);
Das in-place-Verfahren funktioniert nur, wenn die Länge der Eingabedaten mit der der Ausgabe-Daten übereinstimmt.

Oder um es WinAPI gerecht zu machen:
Code:
[b]function[/b] spiegeln(p: PChar; Buffer: PChar; MaxBufferLen: Integer): Integer;
[b]var[/b] s: [b]string[/b];
[b]begin[/b]
  s := p;
  ...
  [b]if[/b] Buffer <> [b]nil then[/b]
    StrLCopy(Buffer, PChar(s), MaxBufferLen); // Daten in Buffer schreiben
  Result := Length(s); // Rückgabewert = Länge des bearbeiteten Strings
[b]end[/b];

[b]var[/b]
  Buf: PChar;
  BufSize: Integer;
[b]begin[/b]
  s := 'Dies ist ein Test';
  BufSize := spiegeln(PChar(s), nil, 0);
  Buf := StrAlloc(BufSize);
  [b]try[/b]
    spiegeln(PChar(s), Buf, BufSize);
  [b]finally[/b]
    StrDipose(Buf);
  [b]end[/b];
  ShowMessage(s);
[b]end[/b];

[i]// Wenn die max. Aufgabelänge bekannt ist, dann geht das auch so:[/i]
[b]var[/b] Buf: [b]array[/b][0..1024] [b]of[/b] Char;
SetString(s, Buf, spiegeln(PChar(s), Buf, 1024));
ShowMessage(s);
Ein function Xyz: PChar; sollte man nur verwenden, wenn man konstante oder global deklarierte Strings einsetzt. Konstante Strings sind nur Strings, die in '' stehen. Wenn ein + oder ein Funktionsaufruf notwendig sind, dann handelt es sich nicht um konstante Strings, da sie erst zur Laufzeit zusammengesetzt werden müssen. Am einfachsten kann man herausbekommen, ob ein String konstant ist oder nicht, indem man sich selbst nur Fragen muss, könnte man diesen String auch so deklarieren:

const MyString = 'Hier steht der zu "prüfende" String';
  Mit Zitat antworten Zitat
Christian Kaufmann

Registriert seit: 5. Aug 2002
7 Beiträge
 
#15
  Alt 30. Aug 2002, 17:23
Alles klar, ich hab einfach übersehen, daß ich mit dem result natürlich einen zeiger auf die stringvariable in der funktion zurückgebe, die natürlich nach dem end dereferenziert wird.
manchmal ist man schrecklich blind
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 13:44 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