Funktion per def-File exportieren



  • Hallo!
    Ich krieg es einfach nicht hin meine DLL-Funktionen per def-File zu exportieren, mit __declspec(dllexport) hingegen klappts super. Das ganz lässt sich auf ganz wenig Code reduzieren:

    .cpp Datei

    #include <windows.h>
    
    void Func() {
        MessageBox(NULL, "Func", NULL, MB_OK);
    }
    

    .def Datei

    LIBRARY NurZumTest
    
    EXPORTS
            Func    @1
    

    Ist da irgendwo ein Fehler drin? Ich habe die .def Datei einfach zu den Quellcode Dateien hinzugefügt. Ich hab irgendwie das Gefühl das er die def-Datei ignoriert. Auch wenn ich da irgendeinen Müll reinschreibe kommen keine Warnungen/Fehler. Bitte helft mir. 🙂



  • Schreib mal extern "C" vor den Funktionsnamen.

    extern "C" void Func(){ /* ... */ }
    


  • Danke für den Hinweis cd9000 🙂 , aber war es leider nicht, aber ich hab's gerade trotzdem herausgefunden. Hatte nur ein Problem mit meinem Compiler. 🙂
    Irgendwie musste man das def file bei Visual C++ 7 explizit in den Linkeroptionen einstellen, es ging nicht durch einfaches Hinzüfügen zu den Quellcode Dateien. Soweit ich mich erinnern kann war das bei Visual C++ 6 nicht so, oder? 😕



  • Nein, bei VisualC++ 6 reicht es die def-datei zu den Quellcodedateien hinzuzufügen.



  • Jo, vielen Dank! Hatte mich echt gewundert. Warum müssen die bloß alles ändern? :p
    Falls es noch jemanden interessiert, die def-Datei muss unter folgendem Option eingestellt werden:

    Projektoptionen -> Linker -> Eingabe -> Moduldefinition

    ciao, Early 🙄



  • Ok, mit einzelnen Funktionen klappt es jetzt. Aber bei C++ Klassen bekomme ich es noch nicht hin. Mit __declspec(dllexport) klappt's wie immer bestens, nur per def-file wieder nicht. 😉

    Das Sourcefile sieht erstmal so aus:

    #include <windows.h>
    
    class CTest {
    public:
        void DoNothing() {
            Sleep(5000);
        }
    };
    

    Dann habe ich einmal mit __declspec(dllexport) kompiliert und im DependencyWalker geöffnet, um an den Namen der Methode zu kommen. Ergebnis:

    ?DoNothing@CTest@@QAEXXZ

    Soweit so gut. Dann hab ich das __declspec(dllexport) wieder entfernt um die Methode jetzt per def-file zu exportieren. Also das ganze ins def-file:

    LIBRARY NurZumTest
    EXPORTS
    ?DoNothing@CTest@@QAEXXZ
    

    Aber beim kompilieren kommt dann folgender Fehler. 😞

    NurZumTest error LNK2001: Nichtaufgeloestes externes Symbol "public: void __thiscall CTest::DoNothing(void)" (?DoNothing@CTest@@QAEXXZ)

    Ich find den Fehler einfach nicht. Das es funktionieren muss, weiss ich aber. Die MFC Bibliothek exportiert ihre Klassen auch über ein def-file.



  • Early schrieb:

    Ok, mit einzelnen Funktionen klappt es jetzt. Aber bei C++ Klassen bekomme ich es noch nicht hin. Mit __declspec(dllexport) klappt's wie immer bestens, nur per def-file wieder nicht. 😉

    Das Sourcefile sieht erstmal so aus:

    #include <windows.h>
    
    class CTest {
    public:
        void DoNothing() {
            Sleep(5000);
        }
    };
    

    Dann habe ich einmal mit __declspec(dllexport) kompiliert und im DependencyWalker geöffnet, um an den Namen der Methode zu kommen. Ergebnis:

    ?DoNothing@CTest@@QAEXXZ

    Soweit so gut. Dann hab ich das __declspec(dllexport) wieder entfernt um die Methode jetzt per def-file zu exportieren. Also das ganze ins def-file:

    LIBRARY NurZumTest
    EXPORTS
    ?DoNothing@CTest@@QAEXXZ
    

    Aber beim kompilieren kommt dann folgender Fehler. 😞

    NurZumTest error LNK2001: Nichtaufgeloestes externes Symbol "public: void __thiscall CTest::DoNothing(void)" (?DoNothing@CTest@@QAEXXZ)

    Ich find den Fehler einfach nicht. Das es funktionieren muss, weiss ich aber. Die MFC Bibliothek exportiert ihre Klassen auch über ein def-file.

    Klassen können nicht per *.def Datei (welche eigentlich nur notwendig ist, wenn man an funktionen der dll per GetProcAddress rankommen möchte) exportiert werden.

    Du kannst dir aber eine sogenannte Factory funktion erstellen, welche dir ein objekt der Klasse erzeugt und einen zeiger darauf zurückliefert.
    z.b.

    CWin32Dll* CreateInstance()
    {
        return new CWin32Dll();
    }
    

    Eventuell ist es noch sinnvoll eine 2. Funktion zu exportieren, welche das Objekt, das du über die Factory Funktion bekommen hast, wieder im DLL Context zerstört
    z.b.

    void Destroy(CWin32Dll* pInstance)
    {
        delete pInstance;
    }
    

Anmelden zum Antworten