Announcement

Collapse
No announcement yet.

DLL und ShareMem

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • DLL und ShareMem

    Hallo,

    obwohl ich direkt keine LongStrings oder dynamische Arrays als Übergabeparameter von/zur DLL benutze, stürzt mein Programm ohne ShareMem zuverlässig nach Minuten ab.

    Was wäre an folgender Konstruktion erlaubt, was nicht, und wie geht es besser, wenn ich kein ShareMem benutzen will ?

    //***** Mainprogramm *****
    procedure Main.Test (a: array of Integer; s: String);
    begin
    DLL_Test(@a[0], Length(a), PChar(s));
    //Oder muss ich hier mit New Speicher besorgen und das Array kopieren?
    end.

    //***** DLL *****
    type TaInt = array[0..1000] of Integer;
    PaInt = ^TaInt;
    var s: String;
    a: array of Integer;

    procedure DLL.Test (p: PaInt; lenWord; pc:PChar);
    var i: Integer;
    begin
    SetLength(a, len);
    MoveMem(@a[0], p, len * SizeOf(Integer));
    oder: for i:= 0 to len - 1 do a[i]:= p^[i];
    s:= pc;
    end;

    Danke pk

  • #2
    Wenn Du ohne ShareMem auskommen willst, solltest Du Dir genau überlegen, wo Speicher angefordert und folglich auch verworfen wird. Initialisierst Du in der DLL also ein Array aus dem Hauptprogramm, kommst Du meiner Meinung nach um ShareMem nicht herum. Setzt du die Größe des Arrays aber im Hauptprogramm und änderst nur noch den Inhalt, sehe ich keine Probleme.<p>
    Immer drüber nachdenken: Wenn Du aus der Dll-Funktion zurückkommst, sollte der in der DLL angeforderte Speicher auch wieder freigegeben sein.<p>
    Mari
    Schöne Grüße, Mario

    Comment


    • #3
      Hallo,

      Danke für die Info.
      Wie in meinem Beispiel gezeigt, gebe ich jeden Speicher immer da frei, wo ich ihn auch anforder. Zusätzlich verpointer ich jedes Array, bzw. Strings, und kopiere sogar in allen aufgerufenen Methoden sofort um. Ein Verändern von übergebenen Arrays bzw. Strings mache ich also grundsätzlich nicht, und ich benutze als Übergabeparameter ausschließlich Single, Integer, PChar, und natürlich Pointer.

      Natürlich alloziiere ich in der DLL-Initialisierung jede Menge dynamische Arrays und andere Daten, die aber nur in der DLL benutzt werden, bzw. als Pointer ausschließlich zum Lesen übergeben werden. Den Speicher gebe ich ordentlich bei Programmende bzw. DLL-Ende wieder frei.

      Darf man vielleicht selbst Pointer auf dynamische Arrays nicht übergeben? Ich meine doch, denn PChar(String) ist auch nichts anderes.

      Meine DLLs müssen ohne ShareMem auskommen, da sie mit "C" kompatibel sein müssen. Oder gibt es als schlechte "Notlösung" ein ShareMem für "C"?

      Danke pk

      Comment


      • #4
        Hmm, noch mal drübergeschaut: Du übergibst an die DLL PChar(s). Das übernimmst Du in Deiner DLL in eine String-Variable, die dann stehen bleibt. Hast Du ShareMem nicht eingbunden, bekommt Delphi das vermutlich nicht mit ---- Delphi gibt also im Hauptprogramm Deinen String wieder frei (oder kopiert ihn um) und die DLL benötigt ihn noch. Du müsstest in der DLL den String durch ein PChar ersetzen, dafür den Speicher holen, Wert reinkopieren, vermute ich....<p>
        Schöne Grüße, Mari
        Schöne Grüße, Mario

        Comment


        • #5
          Hallo,

          das Problem ist gelöst. Ich habe mir erlaubt ein neues Thema mit dem Titel "DLL und Thread, Vorsicht Falle" zu eröffnen.

          Gruß pk

          Comment

          Working...
          X