2010-11-26 3 views
2

Ich Zuteilung Speicher für mehrere PWideChar auf meinem Haupt-ausführbare DateiWo/Wann PWideChars frei an externe DLL gesendet

var 
    pwcValor: PWideChar; 
begin 
    pwcValor := AllocMem(sizeof(WideChar) * Succ(Length(pValor))); 
    StringToWideChar(pValor, pwcValor, Succ(Length(pValor))); 
    pMetodo(pCodigo, pCodigoParametro, pwcValor); 

Alle diese Variablen werden auf eine externe DLL gesendet über die späte Bindung verwenden. Ich habe einige Fragen zu dieser Situation, um Speicherlecks zu vermeiden.

  • Wo (auf meiner exe oder meiner dll) sollte ich die FreeMem auf diesen Variablen aufrufen?
  • Muss ich FreeMem für diese Variablen aufrufen?
  • Wann kann (oder soll ich) FreeMem für diese Variablen aufrufen?
  • Wenn ich sie innerhalb der externen DLL (die auch meine ist) aufrufen, erhalte ich Zugriffsverletzungen, wenn ich versuche, die DLL-Bibliothek aus dem Speicher zu entladen.
    Tks

    EDIT

    Etwas, was ich zu fragen, vergessen zu. Und umgekehrt? Ich habe also Rückgabeparameter von meiner DLL zur EXE, also sind die PWideChars auf die DLL zugeteilt. Also, ich müsste sie auf der DLL freigeben, oder? Aber ich werde sie wahrscheinlich immer noch auf der EXE verwenden. Muss ich im EXE vorbelegen, an die DLL den Zeiger senden und in diesen Fällen die DLL ausfüllen? Oder erstellen Sie einfach eine Kopie des zurückgegebenen Parameters in der EXE, damit ich es sicher auf der DLL freigeben kann?

    Antwort

    3

    Letztlich hängt das vom Design der DLLs ab, die Sie verwenden. Ich würde jedoch sagen, dass, wenn nicht anders dokumentiert, es sicher ist, die Ressourcen freizugeben, sobald die DLL-Funktion zurückkehrt. Ich würde sogar vorschlagen, dass Sie es tun sollten. Jedenfalls müssen Sie es tun, um Speicherlecks zu vermeiden.

    In Bezug auf den letzten Satz, eine DLL und die aufrufende EXE, obwohl beide Delphi-Code sind, verwenden sie verschiedene Speicher-Manager, so dass Sie nicht in einer DLL freien Speicher in der EXE zugeordnet werden können.

    +0

    @PA, muss ich die Zeiger aller zugewiesenen PWideChars an die DLL gesendet, damit sie später freigegeben werden können, nicht wahr? Eine andere Frage, die ich vergessen habe zu fragen ... und umgekehrt? Ich habe einige PWideChar zurückgegeben, die auf der DLL zugeordnet sind, die ich an die EXE zurückgeben. Ich kann sie in der DLL nicht freigeben, da sie immer noch von der EXE verwendet werden. Tks – Pascal

    +0

    EXE-Code kann Speicher nicht freigegeben durch eine DLL freigeben. Wenn Sie ** Mem ** in der DLL reservieren müssen, dann müssen Sie es in der DLL freigeben, vielleicht in einer Funktion, die von der EXE aufgerufen werden kann, wenn Sie mit dem zurückgegebenen Mem fertig sind. Allerdings würde ich versuchen, DLL-Alloc zu vermeiden, und immer mem von der EXE –

    +0

    Tks für die Antwort @PA! – Pascal

    2

    Bezug zu befreien:

    Es gibt verschiedene mögliche Lösungen hier:

    • Ihr exe-Puffer zuordnen kann, die dann von dll gefüllt werden würde;
    • Ihre DLL kann eine weitere Funktion exportieren, sagen FreeString. Exe sollte es jedes Mal aufrufen, wenn es mit der Zeichenfolge fertig ist;
    • Sie können einfachen WideString-Typ verwenden. Dieser Stringtyp verwendet den Systemspeichermanager, der für exe und dll identisch ist.

    Persönlich empfehle ich Ihnen die letzte Option.

    +0

    Es gibt eine allgemeine Empfehlung gegen die Verwendung des Delphi-String-Typs zum Übergeben von Strings an DLLs. Es gibt kein Problem mit WideStrings in DLLs? – Pascal

    +0

    Ja, WideStrings sind sicher. Mehr noch, in C++ gibt es auch diese Art von Strings, es heißt BSTR. – Torbins

    +0

    Tks für die Spitze, Torbins! – Pascal

    0

    Wenn Sie eine Delphi-String-Variable haben und D2009 oder höher verwenden, damit PChar PWideChar zugeordnet wird, können Sie Ihre Funktion einfach mit pMetodo(pCodigo, pCodigoParametro, PChar(pValor)) aufrufen. Dann nehmen Sie innerhalb Ihrer DLL eine Kopie der Zeichenkette, indem Sie eine Zeichenkettenvariable deklarieren und der Zeichenkette einfach zuweisen. Zum Beispiel würde der DLL-Code wie folgt aussehen:

    Der Code, wie Sie es haben, ist ziemlich unnötig komplex. Wenn ich es so mache, wie ich es vorschlage, muss ich keine expliziten Speicherzuweisungsroutinen verwenden.Wenn du C-Code schreiben willst, dann warum Delphi !! ;-)

    Wenn Sie expliziter sein wollten, dann könnten Sie PWideChar anstelle von PChar schreiben.

    +0

    Tks so viel für Ihren Vorschlag .... aber es ist Delphi 7: -/ – Pascal

    +0

    Sie können immer noch PWideChar schreiben (WideString (...)) und die Zuordnung vermeiden –

    Verwandte Themen