DLL Datei erstellen und benutze



  • Hallo kennt wer ein gutes Tutorial wo VERNÜNFTIG erklärt wird wie man eine eigene DLL Datei erstellt und auch die Funktionen der Datei nutzen kann.

    Die Sachen die ich bisher immer gefunden habe ware nicht so wirklich toll ...



  • Ach ja als IDE verwende ich RAD Studios 2007.



  • Wozu ein Tutorial? DLLs sind eigenständige Projekte mit exportierten Funktionen, die von den Anwendungen zu importieren sind. Unter Windows kommt hinzu, dass die DLL eine eigene Einstiegsfunktion DllMain() braucht. Vernünftige IDEs unterstützen das meiste. Zum generellen Verständnis sind die umfassenden Erklärungen von 'Charles Petzold: Windows-Programmierung' hilfreich und ausreichend.



  • Ja toll ich weiss das dass eigene Projekte.
    Was habe ich davon ? Genau nichts. 😡



  • dll schrieb:

    Ja toll ..... Was habe ich davon ? Genau nichts.

    Dann hast du ein Problem, wenn du selbst nichts lernen möchtest. Ich könnte ein solches Tutorial schreiben, lasse es aber lieber sein! :p



  • Meine DLL:

    #include <vcl.h>
    #include <windows.h>
    #pragma hdrstop
    
    #pragma argsused
    
    __declspec(dllexport) int Min(int X, int Y)
    {
    return X < Y ? X:Y;
    }
    
    int __declspec(dllexport) Max(int X, int Y)
    {
    return X > Y ? X:Y;
    }
    
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
    
            return 1;
    }
    

    Mein Programm zum DLL Laden:

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #include <windows.h>
    #include <iostream.h>
    #pragma hdrstop
    
    //---------------------------------------------------------------------------
    
    #pragma argsused
    
    __declspec(dllimport) int Min(int, int);
    __declspec(dllimport) int Max(int, int);
    
    int main(int argc, char* argv[])
    {
    
    Min(5,4);
    
            return 0;
    }
    

    Fehlermeldung:

    [Linker Fehler] Unresolved external 'Min(int, int)' referenced from C:\DOKUMENTE UND EINSTELLUNGEN\USER\DESKTOP\INJ\CALL\UNIT1.OBJ

    @berniebutt

    Das hat mit nichts lernen wollen rein gar nichts zu tun !

    Ich glaub du weisst selber nicht wie es geht und willst mich nur Ärgern !



  • Der Linker weiss nicht, welche DLL er bereitstellen soll. Das muss ihm schon irgendwie mitgeteilt werden (kann die IDE machen). Ärgern will ich dich jedenfalls nicht. Ich selbst setze DLLs sehr gerne ein und habe damit keine Schwierigkeiten. Für solchen Kleinkram wie Min- Max-Funktionen erscheint mir der Überbau zu gross.



  • Mit den Zeilen:

    __declspec(dllimport) int Min(int, int);
    __declspec(dllimport) int Max(int, int);
    

    ...sagst du bloss dass es Funktionen Min und Max irgendwo gibt, was die für Parameter bekommen und was die zurückliefern.
    Geladen wird damit aber nichts 😉

    Es gibt zwei Möglichkeiten wie die DLL geladen werden kann:
    1. Dein Compiler hat nicht nur die *.dll erzeugt, sondern auch eine *.lib.
    Diese muss du beim Projekt welches deine DLL nutzen soll dem Linker mitteilen. Die DLL wird dann (in aller Regel) direkt beim Programmstart geladen.

    2. Du hast keine *.lib oder willst sie nicht nutzen:
    Du musst die DLL selbst mit LoadLibrary() öffnen, und Zeiger auf die Funktionen in der DLL mittels GetProcAddress() besorgen.
    (und hinterher auch irgendwann mit FreeLibrary() die dll wieder freigeben...)

    Beispiele zu DLLs gibt z.B. bei wikipedia:
    http://de.wikipedia.org/wiki/Dynamic_Link_Library#Programmierbeispiele



  • Implizites Laden der DLL funktioniert jetzt ich hab einfach eine andere IDE genommen.

    Jetzt versuche ich mal das Explizite Laden der DLL ich hab noch ein E-Book gefunden wo die Sachen etwas erklärt werden.

    Mal sehen ob es klappt ...



  • Wieso bekomme ich bei der Variable ret immer 0 ausgeben.

    Die DLL liegt auch im richtigen Ordner was ist den an meiner GetProcAdress Funktion falsch ?

    Ja meine DLL enhält auch die AddNumbers Funktion.

    So steht es in der MSDN:

    FARPROC WINAPI GetProcAddress(
    __in HMODULE hModule,
    __in LPCSTR lpProcName
    );

    hModule [in]

    A handle to the DLL module that contains the function or variable. The LoadLibrary, LoadLibraryEx, or GetModuleHandle function returns this handle.

    The GetProcAddress function does not retrieve addresses from modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx.
    lpProcName [in]

    The function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.
    Return Value

    If the function succeeds, the return value is the address of the exported function or variable.

    If the function fails, the return value is NULL. To get extended error information, call GetLastError.

    #include <windows.h>
    #include <iostream.h>
    
    using namespace std;
    
    int main ()
    {
    
    FARPROC ret;
    HINSTANCE h = LoadLibrary("Project1.dll");
    
    	if (h==0)
    	{
    		cout<<"error"<<endl;
    	}
    
    	else
    
    	ret = GetProcAddress(h, "AddNumbers");
    	cout<<ret;
    
    system("PAUSE");
    
     }
    


  • Warum nimmst du keine .lib ?
    Dann musst du mit deinem Programm schon keine DLLs ausliefern 😃



  • Weil ich das gerne auch so können möchte.



  • Was für Vorteile haben denn DLLs (außer dass das Projekt kleiner ist) ?

    Weil für DLLs muss man halt jede einzelne Funktion importieren..



  • DarkShadow44 schrieb:

    Was für Vorteile haben denn DLLs (außer dass das Projekt kleiner ist) ?

    Weil für DLLs muss man halt jede einzelne Funktion importieren..

    Wenn mehrere Applikationen auf eine DLL zugreifen wird massiv Speicher gespart, das manuelle Entladen bringt auch in einem einzelnen Programm Speicherersparnis.



  • Kann man dann bei DLLs auch Header nutzen ?



  • dll schrieb:

    Die DLL liegt auch im richtigen Ordner was ist den an meiner GetProcAdress Funktion falsch ?

    Möglicherweise heisst die Funktion in der DLL anders.
    Mit diesem Teil kannst du dir angucken welche Funktionen in der DLL sitzen und überprüfen ob die Funktionsnnamen stimmen:
    http://www.dependencywalker.com/

    Sollte der Funktionsname dort anders aussehen, erstelle eine *.def Datei:

    LIBRARY NameDeinerDllOhneEndung
    EXPORTS
       Min              @1
       Max              @2
       NochNeFunktion   @3
    

    Man kann in den Projekteigenschaften bei den meisten C++ IDEs irgendwo ne *.def-Datei angeben (bei VC2008: Linker -> Input -> Module Definition File).
    Gib da die vorher erstellte *.def-Datei an und die Funktionsnamen sollten passen.



  • DarkShadow44 schrieb:

    Kann man dann bei DLLs auch Header nutzen ?

    Klar kann man das und tut es gewöhnlich auch!



  • Hallo mit dem Programm depends von geeky konnte ich den richtigen Funktionsnamen ermitteln jetzt bekomme ich auch die richtige Adresse.

    Nur mein Problem ist jetzt noch das ich nicht weiss wie ich die Funktion nun benutzen kann.

    Hier lad ich die DLL:

    #include <iostream>
    #include <vcl>
    using namespace std;
    
    #pragma hdrstop
    
    #pragma argsused
    
    int main(int argc, char* argv[])
    {
    
    HMODULE  h = LoadLibrary("Project1.dll");
    
    HMODULE ret;
    
    	if (h==0)
    	{
    		cout<<"Project1.dll nicht geladen" << endl;
    	}
    
    	else
    	{
    		ret = GetProcAddress(h,"@ausgabe$qv");
    
    	if (ret == 0)
    	{
    		cout<<"Funktion nachricht nicht gefunden"<<endl;
    	}
    
    	   cout<<"Adress : "<<ret<<endl;
    
    	FreeLibrary( h );
    
    }
    
    	system("PAUSE");
    
    	return 0;
    }
    

    Meine DLL Datei:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <windows.h>
    #include <iostream>
    using namespace std;
    
    #pragma hdrstop
    
    #pragma argsused
    
    __declspec(dllexport) int ausgabe ()
    {
    
    cout<<"Hallo";
    
    return 0;
    }
    
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
    	return 1;
    }
    //---------------------------------------------------------------------------
    


  • Sorry, ich muss mich noch einmal melden!
    Dein letztes Beispiel will eine Windows-DLL mit einer Konsolen-Anwendung verknüpfen. Entweder beides Windows oder beides Konsole wäre sinnvoll. Gemischt düfte es in die Hose gehen.
    Die verschiedenen Wege zum Export und Import der DLL-Funktionen sind dir von anderen Postern nahzu vollständig mitgeteilt worden. Der einfachste Weg ist es, mit implib mydll.lib mydll.dll eine LIB zu machen und diese in die Anwendung einzubinden. Letzteres macht die IDE. Ich verstehe nicht, warum du ohne LIB die DLL einsetzen möchtest.



  • dll schrieb:

    Hallo mit dem Programm depends von geeky konnte ich den richtigen Funktionsnamen ermitteln jetzt bekomme ich auch die richtige Adresse.

    Nur mein Problem ist jetzt noch das ich nicht weiss wie ich die Funktion nun benutzen kann.

    Schau dir mal das wikipedia-Beispiel näher an:
    http://de.wikipedia.org/wiki/Dynamic_Link_Library#Einbinden_von_DLLs_zur_Laufzeit

    (btw: Ich würde lieber die DLL mit ner *.def-Datei erzeugen, der Funktionsname kann sich je nach Compiler-Version sonst möglicherweise mal ändern und die ganze Sache klappt nicht mehr...)


Anmelden zum Antworten