Dll Funktionen in 2 Klassen nutzen?!?



  • Hallo, habe mal wieder ein kleines Problem:

    Ich habe eine DLL und eine dazugehörende Header-Datei, genannt dll.h.
    Dann habe ich 2 Klassen: Class A und Class B. Beides sind Dialoge.
    Beide wollen jetzt auf Funktionen der DLL zugreifen. Wenn ich jetzt in der A.cpp

    #include "dll.h"
    

    hinzufüge, kann ich die Funktionen mit Class A nutzen.
    Füge ich diese Zeile aber auch in B.cpp ein, dann gibt es Linker-Fehler, da die Funktionen schon in der A.obj definiert seien.
    Ich habe jetzt oft versucht, die #include Anweisung einmal in die .cpp, dann wieder in die .h - Dateien hinzufügen, klappt leider nichts.
    Zudem steht in der A.cpp auch noch

    #include "B.h"
    

    , da von A aus der Dialog (B) geöffnet werden soll.
    Also, wie kriege ich das hin, dass beide Klassen die Funktionen der DLL nutzen können? Eine lib-Datei gibt es nicht, bloß die Header-Datei. In der Headerdatei sind auch alle möglichen

    typedefs
    

    und der Funktionsaufruf

    LoadLibrary()
    

    enthalten. Kann ich mit denen vielleicht was machen.
    Mit der Forensuche habe ich nichts treffendes gefunden, ahne schon, dass das Problem zu simpel ist, aber ich steige da irgendwie nicht durch. Wäre für Hilfe wirklich dankbar. 🤡

    😕



  • Paul_C. schrieb:

    In der Headerdatei sind auch alle möglichen

    typedefs
    

    und der Funktionsaufruf

    LoadLibrary()
    

    enthalten. Kann ich mit denen vielleicht was machen.

    Der Funktionsaufruf LoadLibrary() hat in der Headerdatei nichts zu suchen. Verschiebe ihn in eine .cpp Datei.
    Kurt



  • Das ist so, die Dll-Datei und die dll.h sind von einem Hersteller.
    In der Header-Datei sind auch Funktionen eingeführt.
    Eine heisst

    int LoadDll()
    

    Diese Funktion ruft dann

    LoadLibrary()
    

    auf.Laut Hersteller soll man dann in seiner Klasse nur die dll.h einbinden und dann LoadDll() aufrufen.
    Jedoch habe ich halt 2 Klassen, welche auf diese Funktionen zugreifen sollen.
    Wie mache ich das, dass beide die Funktion LoadDLL() bzw. die Funktionen der DLL aufrufen können? 😕



  • Dein Problem ist aber dass wenn du ClassA.cpp komilierst wird LoadDll() in ClassA.obj engebunden und wenn du ClassB.cpp komilierst wird LoadDll() in ClassB.obj eingebunden. Das geht aber nicht da sich der Linker dann nicht entscheiden kann welche der beiden Versionen er verwenden soll.
    Lösung: in "dll.h" kommt nur die declaration

    int LoadDll();
    

    zb in ClassA.cpp kommt die Implementation.

    int LoadDll() {
       LoadLibrary( .... );
       .....
    }
    

    Dann kommt LoadDll() nur in ClassA.obj vor und everything is allright. Aufgerufen wird LoadDll() dann in der main.
    Kurt



  • Ich nehme also die Funktionen zum Loaden aus der dll.h heraus und füge sie dann als Methoden in Class A ein.
    In B.cpp schreibe ich dann nur

    #include "A.h"
    

    ?



  • Nein nicht als methode von Class A, nur als funktion. Kannst sie auch nach main.cpp verschieben. Sie darf einfach nur in einer Kompilationseinheit implementiert werden
    Kurt



  • Ok, habe nun die LoadDLL() in die A.cpp gepackt.
    In B.cpp schreibe ich

    #include "A.h"
    

    Jedoch kann ich dann immer noch nicht auf die Funktionen der Dll zugreifen.
    Wenn ich in B.cpp

    int result = DllFunktion();
    

    schreibe und dann ausführen möchte, dann kommt folgende Meldung:

    g:\Visual C++\B.cpp(118): error C3861: 'DllFunktion': Bezeichner wurde auch mit einer argumentbezogenen Suche nicht gefunden



  • Hast du den Prottyp der Funktion in die Header Datei von A eingetragen



  • Nee, muss ich mal ausprobieren.

    EDIT: Habe damit irgendwie Probleme,die Funktion ist verschachtelt definiert.
    Soll heisse, dass ich nicht mal eben

    int DllFunktion(void)
    

    in die Header-Datei schreiben kann.
    So sieht die Definition in der Headerdatei der Dll aus. Was muss ich also nun in die A.h schreiben?

    typedef		    BYTE (CALLBACK* pDLLUsbGetPortState)         (BYTE, BYTE, BYTE*);
    FARPROC		    lpfnUsbGetPortState;
    pDLLUsbGetPortState UsbGetPortState; 
    lpfnUsbGetPortState = GetProcAddress(HMODULE(hUsb2Dll), "UsbGetPortState");   
    UsbGetPortState     = pDLLUsbGetPortState(lpfnUsbGetPortState);
    

    Oder muss ich auch zusätzlich die LoadFunktion in B.cpp ausführen? <- ok, ist wohl logisch. 🤡



  • Weiss jemand weiter?

    Wenn ich als Prototyp in die A.h

    BYTE UsbGetPortState(BYTE,BYTE,BYTE*);
    

    schreibe, dann sagt der Compiler:

    g:\Visual C++ \Dll.h(133): error C2365: 'UsbGetPortState': Erneute Definition; vorherige Definition war 'Funktion'
    g:\Visual C++\Dll.h(236): error C2659: '=': Überladene Funktion als linker Operand



  • mh, weiß ja nicht, aber haste vielleicht keine includeguards:

    #ifndef _CLASS_A_
    #define _CLASS_A_
    
    ...
    
    #endif
    

    😕



  • Was sollte das ändern?
    Ich habe ein MFC-Projekt. Die Klassen habe ich mit dem Assistenten erzeugt.
    Da steht bei beiden am Anfang der Headerdatei

    #pragma once
    #include "afxwin.h"
    

    .
    Mehr nicht.
    EDIT: Habe es in beiden Headerdateien mal ausprobiert. Leider kein Erfolg. 😞



  • Sitze immer noch an dem Problem und komme nicht weiter. Nun habe ich die dll-Headerdatei weggelassen und schreibe alles selber hin.

    In der B.cpp steht nun

    typedef		BYTE (CALLBACK* pDLLUsbInit) (BYTE);
    FARPROC		lpfnUsbInit;
    pDLLUsbInit	UsbInit;
    

    Unter OnBnClickedTrydll() steht

    void CB::OnBnClickedTrydll()
    {
        BYTE result = 0,init = 0;
        HINSTANCE hUsb2Dll;
        hUsb2Dll = LoadLibrary("usb2.dll");
        if (hUsb2Dll != NULL)
        {
            lpfnUsbInit = GetProcAddress(HMODULE(hUsb2Dll),"UsbInit");
            UsbInit = pDLLUsbInit(lpfnUsbInit);
            UsbInit(init);
            FreeLibrary(hUsb2Dll);
        }
    }
    

    Damit kann ich auch auf die Funktion zugreifen. Schreibe ich das aber auch in die A.cpp, meckert er:

    Dll error LNK2005: "int (__stdcall* lpfnUsbInit)(void)" (?lpfnUsbInit@@3P6GHXZA) already defined in A.obj
    Dll error LNK2005: "unsigned char (__stdcall* UsbInit)(unsigned char)" (?UsbInit@@3P6GEE@ZA) already defined in A.obj

    Kann mir denn keiner weiterhelfen? 😕



  • Habe gerade eben ein kleines Workaround geschafft!! 😉
    schreibe ich in die A.cpp anstatt UsbInit, UsbInit2, dann klappt das:

    typedef		BYTE (CALLBACK* pDLLUsbInit) (BYTE);
    FARPROC		lpfnUsbInit;
    pDLLUsbInit	UsbInit2;
    
    .....
    
    void CA::OnBnClickedDllfunc()
    {
        BYTE result = 0,init = 0;
        HINSTANCE hUsb2Dll;
        hUsb2Dll = LoadLibrary("usb2.dll");
        if (hUsb2Dll != NULL)
        {
            lpfnUsbInit = GetProcAddress(HMODULE(hUsb2Dll),"UsbInit");
            UsbInit2 = pDLLUsbInit(lpfnUsbInit);
            UsbInit2(init);
            FreeLibrary(hUsb2Dll);
        }
    }
    

    Leider muss ich so für jede Funktion die ich brauche alles hinschreiben.
    Es sei denn, freundliche nette Mitglieder haben bessere Vorschläge. 😉



  • Hi,

    Falls Du ein MFC-Projekt hast (habe ich irgendwo gesehen), dann pack die
    Headerdatei deiner DLL einfach in die stdafx.h. Dann hast du in der ganzen
    Applikation Zugriff auf die Funktionen, ohne irgendwo noch mal die
    Headerdatei zu includieren.

    Sollte eigentlich klappen.

    Gruss
    EB


Anmelden zum Antworten