SPcierh richtig freigeben??



  • Hallo,

    ich habe eine DLL, welche eine Klasse hat:

    Dll.h

    #ifndef FILE1_H
    #define FILE1_h
    #include <string>
    class __declspec(dllexport) Test
    {
     public:
      std::string GetIt(){return "hallo";}
    };
    
    #endif
    

    dll.cpp

    #pragma argsused
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
    	return 1;
    }
    
    extern "C" __declspec(dllexport)Test* GetTest()
    {
        return new Test;
    }
    

    Ausführendes Programm
    Main.cpp

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    Test* t;
    typedef Test*(*pFunc)();
    pFunc myFunc;
    HINSTANCE h = LoadLibrary("Project2.dll");
    if(h!=NULL)
       {
         myFunc = (pFunc)GetProcAddress(h,"_GetTest");
         if(myFunc)
            {
              t = pFunc();
              std::string str = t->GetIt();
              ShowMessage(String(str.c_str()));
            }
         else
            {
                ShowMessage("Funktion wurde nicht gefunden");
            }
       }
    else
       {
           ShowMessage("Datei konnte nicht geladen werden");
       }
    FreeLibrary(h);
    }
    

    meine Fragen:
    wo muss der speicher jetzt freigegeben werden?
    kann ich auch eine komplette instanz (kein zeiger) zurückgeben?



  • Hallo,

    Du solltest die Instanz von Test, die du von GetTest() bekommst innerhalb der dll, d.h. mit Hilfe einer dort definierten Funktion freigeben. Es soll zwar theoretisch auch außerhalb gehen, hat bei mir aber noch nie so recht funktioniert.
    Also

    extern "C" __declspec(dllexport)void freeTest(Test* t)
    {
        delete t;
    }
    

    Du solltest keine vollständige Instanz zurückgeben. Das kann gut gehen solange die dll und das ausführende Programm mit dem gleichen Compiler erstellt wurden. Wenn nicht, kann es sein, dass die Klasseninstanzen nicht binärkompatibel sind (mit fällt gerade kein anderer Ausdruck dafür ein). Das trifft übrigens auch auf std::string zu. Wenn die dll mit dem BCB5 erstellt wurde, das aufrufende Programm aber mit dem BCB6, kann es da auch crashen, da beide Compiler unterschiedliche STL-Implementationen verwenden (hatte ich schon mal). Versuche möglichst nur PODs zurückzugeben, wenn du die dll verbreiten willst.



  • und diese methode rufe ich dann im mainprogramm auf, nachdem ich t benutzt habe mit freeTest(t) auf?!



  • Ja.


Anmelden zum Antworten