Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - PChar-Übergabe an DLL -> Sicher vor Veränderungen?


Flamefire - Di 02.11.10 11:29
Titel: PChar-Übergabe an DLL -> Sicher vor Veränderungen?
Ich benutze eine DLL, die als Config einen PAnsiChar nimmt.
Aufruf sieht so aus:

Delphi-Quelltext
1:
RTMP_SetupURL(r,PAnsiChar(AnsiString(s)));                    

in der DLL wird dieser String durchsucht und in AVal Werten gespeichert (also Länge und Pointer auf anfang, der in dem Fall in der Mitte meines Strings liegt)
z.B. so:

C#-Quelltext
1:
2:
3:
4:
5:
AVal x;
void foo(char *bar){
x.av_val=bar+20;
x.av_len=10;
}


Jetzt habe ich aber Bedenken, was die Gültigkeit des PChars angeht. dürfte der nicht sofort nach dem Aufruf ungültig sein und u.U. mit anderen Daten überschrieben werden können, was dazu führt, dass sich die config ändert, obwohl schon gelesen? Es wird ja nicht der String kopiert sondern nur der Pointer auf einen Teil gespeichert.

Wer kann das klären?


jaenicke - Di 02.11.10 12:14

Normalerweise sollte das durch UniqueString automatisch korrigiert werden sobald der String nach dem Cast auf PChar wieder verändert wird. Da bin ich mir in diesem Fall aber durch die Casts (die wiederum Compilermagic zur Folge haben) nicht so sicher.

Damit die Freigabe korrekt funktioniert, ist es denke ich am besten, wenn du in der DLL den Inhalt kopierst statt nur eine Referenz zu halten.


Flamefire - Di 02.11.10 14:45

Nja geht mir halt darum:
AnsiString() wird neuen Speicher reservieren und dann den Unicode-String in Ansi umwandeln. PAnsiChar dann 0-Terminierung prüfen und den Ptr auf das 1. Zeichen zurückgeben.
Nach dem Funktionsaufruf ist die "temporäre" Variable von AnsiString() out-of-scope und der Speicher sollte freigegeben werden (wo sonst?)
Wenn der String dann verändert wird, hat das nix mit UniqueString zu tun, da ja der Speicher an sich freigegeben wurde und da z.b. ein Integer rein könnte...
Die DLL kommt nicht vom mir. Ist die libRTMP.dll. Hab zwar Zugriff auf den Source-Code, aber so kann das ja nicht gedacht sein, oder?


BenBE - Do 04.11.10 19:46

Grundregel beim Schreiben von C-Source: In Funktionen Parameter IMMER selbst kopieren (insbesondere Strings), außer die Funktion gibt selbst an, dass der String verändert wird, was heißt, dass man AUF dem übergebenen Puffer arbeitet.

Für deinen Fall hieße das also: PChar in der DLL kopieren.


jaenicke - Do 04.11.10 20:36

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Für deinen Fall hieße das also: PChar in der DLL kopieren.
Da das eine Fremd-DLL ist, bleiben zwei Möglichkeiten:
Entweder diese korrigieren und selbst kompilieren (so mache ich es in der Regel), oder als Workaround an die DLL einen direkt dafür gespeicherten String als Pointer übergeben, der danach während die DLL damit arbeitet nicht geändert wird.