Speicherverwaltungs Dll & Bedingungen



  • kennt keiner das Problem?
    Anders gefragt:
    Wie kann ich am besten eine DLL-Funktion programmieren, die AnsiString zurückliefert? Es muß doch irgendwie möglich sein, oder?

    Ich wäre für Hilfe sehr dankbar, denn ohne die komme ich nicht weiter. Ich habe gegoogelt und das Problem auch dort gefunden jedoch keine Lösung (außer daß die DLL "mit dynamischen RTL" und "mit Laufzeit Packages" zu erstellen, was mir aber nicht hilft, denn die EXE wird weitergegeben)

    MfG
    xy



  • Warum willst du unbedingt einen AnsiString zurückgeben. 😕 Du könntest doch genauso über AnsiString::c_str() ein *char ** zurückgeben und es am anderen Ende wieder an einen AnsiString übergeben.
    Vielleicht lässt sich so das Problem umgehen. 😃



  • Ich hab gerade oben gesehen, dass du sowas ähnliches versucht hast. Wenn du die ganze Geschichte ein bisschen umschreibst, dann müsste es eigentlich funktionieren.



  • Maffe001 schrieb:

    Warum willst du unbedingt einen AnsiString zurückgeben. 😕 Du könntest doch genauso über AnsiString::c_str() ein *char ** zurückgeben und es am anderen Ende wieder an einen AnsiString übergeben.
    Vielleicht lässt sich so das Problem umgehen. 😃

    Hallo Maffe001,

    das Problem mit AnsiString::c_str() ist hier beschrieben:
    http://www.c-plusplus.net/forum/viewtopic.php?t=39296

    Andere Idee?
    Danke
    xy



  • Hmm, schon klar. Aber wenn du die ganze Sache direkt an einen AnsiString übergibst, dann sollte doch eigentlich alles glatt gehen.

    //DLL.h
    #define DLLEXPORT extern "C" __declspec(dllexport) //der Übersichtlichkeit 
                                                       //halber
    
    DLLEXPORT char *Return_String ();
    //-------------------------------------------------------------
    
    //DLL.cpp
    char *Return_String()
    {
      AnsiString Test = "Dies ist ein Test.";
    
      return Test.c_str();
    }
    //-------------------------------------------------------------
    
    //App.h
    
    #define DLLIMPORT extern "C" __decspec(dllimport) //die Übersicht wieder
    
    DLLIMPORT char *Return_String();
    //-------------------------------------------------------------
    
    //App.cpp
    
    int Get_String ()
    {
      AnsiString TestString = "";
    
      TestString = AnsiString(Return_String());
      return ...;
    }
    //-------------------------------------------------------------
    

    So hab ich mir jetzt das Ganze gedacht. Da die Übergabe passiert ist, sollte es doch keine Probleme mehr geben.
    Ich muss dazu sagen, dass ich das selber noch nicht gemacht habe. Ist nur so ne Idee, wie ich da ran gehen würde. 😃



  • Am Anfang hatte ich es auch so versucht, und ich kann mich erinnern, daß ich dann ein "Access Violation" bekommen habe. Dann habe ich bei der Suche den oben genannten Beitrag gefunden.
    Ich versuche es trotzdem nochmal.

    Danke
    xy



  • Sag mal Bescheid, wenn's klappt. Muss doch wissen, ob meine geistigen Ergüsse auch was taugen. 😃



  • Maffe001 schrieb:

    Du könntest doch genauso über AnsiString::c_str() ein *char ** zurückgeben und es am anderen Ende wieder an einen AnsiString übergeben.

    Wenn ich das nur schon lese wird mir schlecht.... Mal wieder ein typisches Beispiel für das Sprichwort "Der schlimmste Schlag ist der Ratschlag"...

    Vielleicht solltest du mal in der FAQ hier nachschauen was über die Verwendung von c_str() so an bemerkenswertem steht...

    -junix



  • Wenn mein "Ratschlag" so schlimm ist. Dann klär mich auf. Ich bin ja gern bereit zu lernen.
    Ich dachte halt, dass es vielleicht gar nicht so schlecht ist, wenn er ein *char ** zurückgibt. So kann er vielleicht seine DLL auch bei anderen Compilern mit einbauen. So weit ich weiss, ist doch AnsiString borlandspezifisch, oder nicht? 😕



  • junix schrieb:

    Vielleicht solltest du mal in der FAQ hier nachschauen was über die Verwendung von c_str() so an bemerkenswertem steht...

    Hallo junix,

    ich hatte ihm schon darauf aufmerksam gemacht.

    xy schrieb:

    Hallo Maffe001,

    das Problem mit AnsiString::c_str() ist hier beschrieben:
    http://www.c-plusplus.net/forum/viewtopic.php?t=39296

    MfG
    xy



  • Ich zitier mich zwar nicht gerne selber aber...

    junix schrieb:

    [...]Vielleicht solltest du mal in der FAQ hier nachschauen was über die Verwendung von c_str() so an bemerkenswertem steht...

    Euch sollte man allen mal eine Implementation von delete bzw. delete [] aufs Auge drücken, welche die Daten vom freigegebenen Speicherbereich zurücksetzt. Auf das ihr begreift, was da genau im Hintergrund abläuft.

    Die von dir vorgeschlagene Version ist besonders gefährlich, da das AnsiString Objekt welches den Zeiger zurückliefert nach dem Return gar nicht mehr existiert.

    -junix



  • Das mit c_str() ist mir schon bewusst. Ich bin ja nu nicht ganz verblödet. Nur über die Geschichte, was mit dem String nach dem return passiert, habe ich nicht nachgedacht. 😞

    Aber gut man lernt ja nie aus. Dann ist mein Vorschlag jetzt, den String in eine Datei zu schreiben, ein Event zu setzen, ihn auslesen und die Datei löschen. Das mit dem Event ist vielleicht sogar noch nicht einmal nötig, da man ja über eine Funktion das regeln könnte, wann er schreibt. Allerdings sollte man die Datei vielleicht von einem Mutex schützen lassen, da auch erst gelesen werden soll, wenn fertig geschrieben ist.
    Klingt ganz schön umständlich, was? Meinungen dazu?



  • @junix,
    Könntest Du bitte folgendes genauer erklären?

    junix schrieb:

    Euch sollte man allen mal eine Implementation von delete bzw. delete [] aufs Auge drücken, welche die Daten vom freigegebenen Speicherbereich zurücksetzt. Auf das ihr begreift, was da genau im Hintergrund abläuft.

    @Maffe001,
    wenn es nicht anders geht, dann würde ich (ganz am Ende) Deinen Vorschlag mit der Datei versuchen.

    Danke
    xy


  • Mod

    Hallo

    warum eine Datei schreiben usw.....

    es gibt doch CallByRef

    MfG
    Klaus



  • @xy: Was gibts da zu erklären? Nach einem delete wird der Speicher freigegeben, das heisst, anders ausgedrückt, die Daten auf die der Zeiger zeigt (geile kombo) sind nicht mehr konsistent und können jederzeit überschrieben werden => Zeiger wird ungültig. Da nun aber ein normaler PC soviel speicher hat, sind die Daten in den häufigsten Fällen noch lesbar.

    @Maffe: zu umständlich. Wieso nicht einfach einen Zeigerszeiger übergeben und innerhalb der DLL dann Speicher reservieren, und dann den String kopieren? Problem: Es darf dann nicht vergessen werden den Speicher wieder freizugeben.

    Oder einfach die WinAPI-Variante: Die Funktion erwartet einen Puffer mit einer maximalen Länge und liefert die Anzahl Zeichen zurück die sie gebraucht hätte. So kann man die Funktion aufrufen mit einem Zeiger auf NULL, die Länge die benötigt wird ermitteln und anschliessend die Funktion nochmals mit Puffer aufrufen. Zum Beispiel.

    -junix

    <edit>Call by Reference wie KlausB es beschrieben hat wäre natürlich auch ne Variante (o:</edit>



  • Die Zeigerszeiger-Idee finde ich am besten. Schade, dass ich nicht daran gedacht habe. 🙂



  • Vielen Dank für die Vorschläge.
    Ich schaue mal, wie ich das realisieren kann. (ehrlich gesagt, habe ich so etwas noch nie gemacht)

    MfG
    xy



  • Maffe001 schrieb:

    Die Zeigerszeiger-Idee finde ich am besten.

    Ich nicht. Die Gefahr für Speicherlöcher ist definitv am höchsten.

    @xy: tja, das ist das Schicksal eines Entwicklers, dass er sich immer wieder mit dingen konfrontiert sieht, die er noch nie gemacht hat..

    -junix



  • Aber wenn man da von Anfang an hinterher ist und gleich immer wieder alles freigibt, wenn man es nicht mehr braucht, dann ist das doch ne feine Sache. Oder etwa nicht? 😕



  • Klar. Ist einfach ne Problem-/Fehlerquelle mehr welche man sich da schafft. Mir persönlich gefällt das WinAPI system am besten.

    -junix


Anmelden zum Antworten