DLLs aufrufen und dessen Funktionen ausführen



  • Hallo Leute,

    Ich hab jetzt endlich mal was mit DLLs gemacht, allerdings in PureBasic, aber das macht ja nichts denn DLLs kann man ja auch verwänden um in einer Sprache etwas zu schreiben und die DLL dann in einer anderen Sprache wieder zu verwänden

    So habe ich das auch mit PureBasic und Blitz3D gemacht, in PB geschrieben und in B3D die DLL genutzt.

    Das möchte ich jetzt auch mal mit C++ machen, also so zu sagen als Notlösung um Dinge, die ich in C++ noch nicht kann aber dafür in anderen Sprachen, durch DLLs zu nutzen.
    Aber ich weiß nicht welche Bibliothek ich dafür laden muss und wie die Funktionen heißen um eine DLL Funktion auf zu rufen.

    Kann mir da vielleicht jemand einen kleinen BeispielCode in`s Forum tippen?
    Sollte doch nicht so lang sein, oder?!

    Gruß LukasBanana



  • Hi,

    Erstmal zur Defninition der Funktionen, die in der DLL ausgelagert werden sollen. Die folgende Datei wird dann zur DLL kompiliert:

    dll.cpp:

    #include "dll.h"
    #include <windows.h>
    #include <iostream>
    
    void hallo()
    {
      std::cout<<"HALLO AUS DER DLL !!!!";
    }
    
    BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                           DWORD reason        /* Reason this function is being called. */ ,
                           LPVOID reserved     /* Not used. */ )
    {
        switch (reason)
        {
          case DLL_PROCESS_ATTACH:
            break;
    
          case DLL_PROCESS_DETACH:
            break;
    
          case DLL_THREAD_ATTACH:
            break;
    
          case DLL_THREAD_DETACH:
            break;
        }
    
        /* Returns TRUE on success, FALSE on failure */
        return TRUE;
    }
    

    Nun die dazugehörige Headerdatei (benötigt man zur Kompilierung der DLL:)

    #ifndef _DLL_H_
    #define _DLL_H_
    
    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */
    
    extern "C"
    {
        DLLIMPORT void hallo ();
    }
    
    #endif
    

    Nachdem du nun die DLL erfolgreich kompilert hast, kannst du sie nun wiefolgt anwenden;

    #include <iostream>
    #include <windows.h>
    
    using namespace std;
    
    typedef void (*ptrhallo)();
    
    int main ()
    {
    
         ptrhallo MeineDllFunktion;
         HINSTANCE hLib;
    
         //Holt mir das Handle auf die DLL
         hLib = LoadLibrary("Sleep.dll");
         BOOL status;
    
         if (hLib)
         {
              MeineDllFunktion = (ptrhallo) GetProcAddress(hLib, "hallo");
              MeineDllFunktion ();
         }
         else
            cout << "Fehler: Konnte die Funktion nicht aufrufen" <<"\n";
    
         status = FreeLibrary(hLib); //Löst das Handle wieder
         getchar ();
         return 0;
    }
    

    Hoffe das hilft weiter MfG mikey.



  • Hallo

    Wie kann ich mehrere Klassen verteilt auf jeweils eine 1 Header und eine Sourcedatei nun zu einer dll zusammenfassen?

    Das mit dem Codebeispiel ist dabei sehr nützlich.

    chrische



  • Du kannst nach oben beschriebenen Schema beliebig viele Dateien zu einer DLL zusammenfassen. Nur die DllMain benötigst du nur in einem einzigen Sourcefile deines DLL-Projekts.

    MfG SideWinder



  • Hallo

    SideWinder schrieb:

    Du kannst nach oben beschriebenen Schema beliebig viele Dateien zu einer DLL zusammenfassen. Nur die DllMain benötigst du nur in einem einzigen Sourcefile deines DLL-Projekts.

    MfG SideWinder

    Genau daran bin ich immer gescheitert. Das es geht, weiß ich ja, nur bekomme ich es nicht hin.

    chrische



  • Für die Zeit die du dich hier schon rumtreibst gibst du aber immer noch sehr tolle Fehlerbeschreibungen ab 👍

    MfG SideWinder



  • Verschiebt das bitte noch in's WinAPI Subforum.



  • Hey "mikey", danke für dein Beispiel 🙂
    Ich hab bloß noch ein kleines Problem:
    wenn ich dann die Funktion "MeineDllFunktion();" aufrufe kommt das beliebte Windows Fenster "Problem senden/ nicht senden".
    Da ich DLL Programmierung in C++ noch nicht gemacht habe kann ich mir nicht helfen 😞 , weißt du vielleicht woran das Problem liegen kann?



  • Hmm hab den selben Code bei mir ausprobiert, kommt auch die Fehlermeldung. Hab grad keine Ahnung, an was das liegen könnte, aber wenn der Thread mal in's WinAPI Land verschoben werden würde, könnte man dir sicher besser helfen. Leider kann ich mir jetzt selber nichtmehr unter die Arme greifen, vorher klappte das noch... Warte mal etwas ab, mal sehen was die anderen dazu sagen 🙂



  • Da habt ihr wahrscheinlich was beim Linken der Standard-Bibliothek verkackt 😃

    MfG SideWinder



  • Das ist eher ein Kompilerproblem. Stichwort : "name-mangeling"

    Die DLL enthält bestimmt eine Export-Funktion namens "_hallo" oder noch abgefahrener.

    Probier mal die Funktion als CALLBACK zu deklarieren :

    extern "C"
    {
    //    DLLIMPORT void hallo ();
        DLLIMPORT void CALLBACK hallo ();
    }
    
    // void hallo()
    void CALLBACK hallo()
    {
      std::cout<<"HALLO AUS DER DLL !!!!";
    }
    


  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • chrische5 schrieb:

    Hallo

    Wie kann ich mehrere Klassen verteilt auf jeweils eine 1 Header und eine Sourcedatei nun zu einer dll zusammenfassen?

    Das mit dem Codebeispiel ist dabei sehr nützlich.

    chrische

    Du benutzt einfach bei der Deklaration der Klasse das Schlüsselwort __declspec(dllexport), Beispiel:
    CExample.hpp:

    class __declspec(dllexport) CExample
    {
       private:
         int m_iValue;
         // usw...
       public:
         CExample(void);
         ~CExample(void);
    
         int GetValue(void) const;
         void SetValue(int iNew);
         // usw...
    }
    

    CExample.cpp:

    CExample::CExample(void)
    {
       m_iValue = 0;
       // ...
    }
    
    CExample::~CExample(void)
    {
       // ...
    }
    
    int CExample::GetValue(void) const
    {
       // ...
       return (m_iValue);
    }
    
    void CExample::SetValue(int iNew)
    {
       m_iValue = iNew;
       // ...
    }
    

    Die Dateien einfach mit ins DLL-Projekt, compilieren und gut ist 😉 .

    PS: Hier darf natürlich NICHT das Schlüsselwort extern "C" verwendet werden!



  • Also als ich das, was "CodeFinder" geschrieben hat, hinzugefügt habe, hat gar nichts mehr funktioniert 😞
    Weiß denn keiner warum ich die geladene DLL Funktion nicht aufrufen kann?



  • SideWinder hat ja auch chrische geantwortet, nicht dir. Immer das selbe, wenn manche Leute mitten in einen Thread platzen, und dort ihre Fragen stellen...



  • Hey mikey: hast du das Problem schon behoben? Ich brauch Hilfe zum Thema DLLs 😞



  • Nee leider nicht, ich weis auch nicht an was es liegt 😞 Sorry



  • Vielleicht sollte das Problem nochmal beschrieben werden, mit Beispielcode!
    Im Prinzip gibt es 2 Sachen zu beachten:
    will man eine Klasse in eine DLL packen, so kann diese DLL nicht mehr dynamisch sondern nur noch statisch gelinkt werden (ja mit ein paar Assembler tricks kann man das umgehen, aber das ist nicht Sinn des Erfinders). Dabei werden die Funktionsnamen geändert (name-mangling) damit keiner auf die Idee kommt, direkt eine Funktion auszuführen.
    Will man stattdessen einfach nur irgendwelche Funktionen in eine DLL packen, die von verschiedenen Programmiersprachen benutzt werden können, so muss man dieses name-mangling ausschalten (mit extern "C").

    DLLMain braucht man nicht unbedingt, nur wenn man explizit auf das Laden, Entladen der DLL reagieren möchte.

    Einfaches Beispiel für eine DLL die eine kleine Funktion exportiert:

    extern "C" __declspec(dllexport) void test()
    {
    MessageBox(NULL, "Hello World", "", MB_OK);
    }
    

    Oder hab ich jetzt auf die falsche Frage reagiert bzw. war das gar nicht die Frage?!

    PS: obiges Beispiel gilt nur für MSVS, keine Ahnung wie die Syntax für andere Compiler lautet.



  • Du scheinst dich mit DLLs aus zu kennen, dann kann ich dich ja noch mal direkt fragen, ob du mir einen (so einfach wie möglich, aber gerne mit Beschreibung), Beipsiel Code schreiben könntest der einmal eine Funktion als DLL exportiert und ein Beispiel Code der diese Funktion aus der DLL wieder importiert!
    Würde mich über die zwei BeispielCodes echt freuen, Danke! 🙂



  • Die Exportierung habe ich oben beschrieben - Du erstellt einfach ein Win32 Projekt, dann unter den Einstellungen wählst du eine DLL aus und haust die oben beschriebene Fkt. in eine CPP Datei und voila, die DLL ist fertig (angenommen Du arbeitest mit VS2005)

    Die DLL kann entweder statisch oder dynamisch geladen werden. Ich werde jetzt erstmal auf die dynamische Variante eingehen:

    irgendwo in der main:

    HMODULE hDLL = LoadLibrary("Dllname.dll");
    void (*pfunc)() = (void (*)()) GetProcAddress(hDLL, "test");
    pfunc();
    

    Damit wird dann die test() Funktion in der DLL aufgerufen. Achtung, es wurde keine Fehlerüberprüfung durchgeführt...
    Wichtig ist nur, dass die DLL auch auffindbar ist 🙂 Sonst liefert LoadLibrary() NULL.

    Logisch soweit?


Anmelden zum Antworten