AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein .NET-Framework (managed code) C# Stringübergabe in eine Delphi Win32-DLL

Stringübergabe in eine Delphi Win32-DLL

Ein Thema von little_budda · begonnen am 18. Aug 2012 · letzter Beitrag vom 20. Aug 2012
Antwort Antwort
Benutzerbild von himitsu
himitsu

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

AW: Stringübergabe in eine Delphi Win32-DLL

  Alt 19. Aug 2012, 12:29
// EDIT:
Um hier keine unbewiesenen Behauptungen zu posten... kleines Beispiel:
Delphi-Quellcode:
function Test(const Value: string): PChar;
begin
  Result := PChar(DupeString(Value, 10));
end;

procedure TForm240.FormCreate(Sender: TObject);
var
  TestResult1, TestResult2: PChar;
begin
  TestResult1 := Test('a');
  TestResult2 := Test('b');
  ShowMessage(TestResult1);
  ShowMessage(TestResult2);
end;
Du wirst sehen, dass (zumindest unter XE) zweimal 10xb ausgegeben wird. Einfach weil die selbe Speicheradresse wiederverwendet wird bevor der erste String ausgegeben wird... Und das ist ja auch vollkommen korrekt, da der Speicherbereich schon wieder freigegeben ist. Dass darauf noch ein Pointer existiert, darf nicht passieren. Deshalb ist der Code so schlicht fehlerhaft.
Das aber auch nur, wenn der Speicher in der Zwischenzeit nicht wieder (komplett) freigegeben oder überschrieben wird.
Denn FastMM behält sich Speicher noch eine Weile, um ihn schneller wiederverwenden zu können und nicht jedesmal langwierig bei Windows beantragen zu müssen.

DupeString liefert eine Stringvariable zurück, wofür Delphi eine temporäre Variable anlegt, welche bei Funktionsende wieder freigegeben wird.
Delphi-Quellcode:
function Test(const Value: string): PChar;
var
  Temp: string;
begin
  Temp := DupeString(Value, 10);
  Result := PChar(Temp);
end; // und im FunktionsENDe steht quasi ein Temp := '';
Und es ist Zufall, wenn hier wieder die selbe PChar-Adresse zurückgegeben wird.
Nämlich nur dann, wenn FastMM zufällig den selben Speicherbereich für den Result-String von DupeString wiederverwendet. (was bei einer so einfachen Funktion und bei SingleThreadding zufällig etwas öfters passieren kann, da die Berechnung/Ermittling des nächst freien Speicherblocks ja gleich abläuft)
Tipp: Versuch es mal mit einem größeren String, wie z.B. DupeString(Value, 1000000000); , denn da ist es wahrscheinlich, daß FastMM den "großen" Speicher sofort wieder an Windows zurückgibt.

Sowas wäre eher möglich, aber das ist natürlich nicht für Multithread, also nicht für mehrere gleichzeitige Aufrufe dieser Funktion, da es nur einen StringSpeicher gibt.
Delphi-Quellcode:
var
  Test_Result: string; // den String auch noch nach dem Funktionsende erhalten

function Test(const Value: string): PChar;
begin
  Test_Result := DupeString(Value, 10);
  Result := PChar(Test_Result);
end;

procedure TForm240.FormCreate(Sender: TObject);
var
  TestResult1, TestResult2: string; // Rckgabewerte sofort in einen String umwandeln, also kopieren
begin
  TestResult1 := Test('a');
  TestResult2 := Test('b');
  ShowMessage(TestResult1);
  ShowMessage(TestResult2);
end;
Einfacher ist ShareMem und direkte Stringübergabe, oder die Verwendung von WideString.
WideString ist eine Kaspelung von String-APIs der OleAut32.dll (MSDN-Library durchsuchenSysAllocStringLen MSDN-Library durchsuchenSysStringLen MSDN-Library durchsuchenSysFreeString) und ist somit auch immer gleich und unabhängig vom Delphi-Speichermanager.

Schlecht ist es auch, wenn keine generischen Typen verwendet werden.
PChar und String können sich je nach Compiler (z.B. vor und nach ab Delphi 2009) verändern und schon verändert sich auch die Schnittstelle (PAnsiChar <> PWideChar | AnsiString <> UnicodeString), aber Schnittstellen müssen statisch/unveränderlich sein.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (19. Aug 2012 um 12:44 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: Stringübergabe in eine Delphi Win32-DLL

  Alt 19. Aug 2012, 12:52
Wäre deine Delphi DLL keine "normale" DLL sondern eine Active-X DLL, dann müsstest du in C# nichts deklarieren sondern könntest ganz bequem die DLL per Referenz einbinden.
Dabei zwingt dich Active-X nur Datentypen zu verwenden, die auch über Prozessgrenzen gemarshalled werden können.
Hier ist eine Übersicht dazu:
http://www.dynamsoft.com/help/twain/...ataMapping.htm
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#3

AW: Stringübergabe in eine Delphi Win32-DLL

  Alt 19. Aug 2012, 22:23
Wenn du der CLR sagst, sie solle einen Parameter als BStr behandeln, dann muss das auch einer sein.
Delphis Implementierung von einem Ole-String (BStr) heißt WideString.
Damit gibt es auch weniger Ärger beim Speichermanagement.

ps: @EWeiss gibst du dir eigentlich tatsächlich Mühe alle möglichen Clichés über VB'ler zu bestätigen?
Anders kann man diesen Cargo-Kult gar nicht anders erklären, den man bei dir öfters rauslesen kann...
Wer immer diesen Thread liest: büdde sucht euch einen anderen Job wenn ihr jemals sowas denkt:
Zitat:
solange es funktioniert und keine Fehlermeldungen seitens
der Anwender kommen lasse ich es erstmal so wie es ist.
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: Stringübergabe in eine Delphi Win32-DLL

  Alt 20. Aug 2012, 00:13
Zitat:
EWeiss gibst du dir eigentlich tatsächlich Mühe alle möglichen Clichés über VB'ler zu bestätigen?
Jo Danke..
Ich strenge mich an dir gerecht zu werden.

gruss
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#5

AW: Stringübergabe in eine Delphi Win32-DLL

  Alt 20. Aug 2012, 07:05
Das nennt sich dann 'beratungsresistent'.
...hat das noch nie in irgendeiner Anwendung probleme bereitet.
Und geknallt hat es schon gar nicht...
Erinnert mich an den Ausspruch einer verstorbenen Freundin:
Zitat:
Ich schnall mich nicht an, es ist bisher ja noch die was passiert
Sie hatte dann einen Autounfall. Unangeschnallt. Jedesmal, wenn mir ein Programmierer erzählt 'Wieso? Läuft doch' fällt mir meine Freundin ein.

Zitat:
Aber der ist closed Source.
Und das ist vielleicht auch besser so.

Ich verwende übrigens OleVariants, das klappt auch. Der Link mit den Datentypen ist aber interessant.
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#6

AW: Stringübergabe in eine Delphi Win32-DLL

  Alt 20. Aug 2012, 07:52
Du bist und bleibst ein dummer Sprücheklopfer und einer der Leute die die Klugheit mit Löffeln gefressen haben.
Hast dich mal gefragt warum du mit vielen hier nicht klar kommst?

Und wieder werden "OT" Beiträge, generiert von Furtbichler, gelöscht werden.
Du lernst es nie.. Die sogenannten Übermenschen.

PS:
opss. vergessen.
Ist schon arg wenn Studierte Leute wie du trotzdem nichts auf die Reihe bekommen.
Kann die Leute in deinen Team nur bedauern.
Schneide dir mal NUR eine kleine Scheibe von "himitsu" ab der hat's drauf
Da kannst auch du mit sicherheit noch was von lernen.

gruss

Geändert von EWeiss (20. Aug 2012 um 08:44 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 16:17 Uhr.
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