QtCreator Dll einbinden



  • ?? wiso definierst du selbst die funktion?
    Die definition der funktion sollte im header stehen.

    Und der fehler hat nichts mit der DLL zu tun, es ist ein compiler fehler und kein fehler des linkers.
    Wie ich schon sagte kann der Compile keine definition einer Funktion mit dem Namen DasUsbCommand finden.

    Zeig mal den inhalt des headers (falls es dir gestattet ist).



  • steht sie aber nicht 😞

    #ifndef DASHARD_H
    #define DASHARD_H
    
    #define DHC_SIUDI0				0		// COMMAND
    #define DHC_SIUDI1				100		// COMMAND
    #define DHC_SIUDI2				200		// COMMAND
    #define DHC_SIUDI3				300		// COMMAND
    #define DHC_SIUDI4				400		// COMMAND
    #define DHC_SIUDI5				500		// COMMAND
    #define DHC_SIUDI6				600		// COMMAND
    #define DHC_SIUDI7				700		// COMMAND
    #define DHC_SIUDI8				800		// COMMAND
    #define DHC_SIUDI9				900		// COMMAND
    
    #define DHC_OPEN				1		// COMMAND
    #define DHC_CLOSE				2		// COMMAND
    #define DHC_DMXOUTOFF			3		// COMMAND
    #define DHC_DMXOUT				4		// COMMAND
    #define DHC_PORTREAD			5		// COMMAND
    #define DHC_PORTCONFIG			6		// COMMAND
    #define DHC_VERSION				7		// COMMAND
    #define DHC_DMXIN				8		// COMMAND
    #define DHC_INIT				9		// COMMAND
    #define DHC_EXIT				10		// COMMAND
    #define DHC_DMXSCODE			11		// COMMAND
    #define DHC_DMX2ENABLE			12		// COMMAND
    #define DHC_DMX2OUT				13		// COMMAND
    #define DHC_SERIAL				14		// COMMAND
    #define DHC_TRANSPORT			15		// COMMAND
    #define DHC_DMXENABLE			16		// COMMAND
    #define DHC_DMX3ENABLE			17		// COMMAND
    #define DHC_DMX3OUT				18		// COMMAND
    #define DHC_DMX2IN				19		// COMMAND
    #define DHC_DMX3IN				20		// COMMAND
    
    #define DHC_WRITEMEMORY			21		// COMMAND
    #define DHC_READMEMORY			22		// COMMAND
    #define DHC_SIZEMEMORY			23		// COMMAND
    
    #define DHE_OK					1		// RETURN NO ERROR
    #define DHE_NOTHINGTODO			2		// RETURN NO ERROR
    
    #define DHE_ERROR_COMMAND		-1		// RETURN ERROR
    #define DHE_ERROR_NOTOPEN		-2		// RETURN ERROR
    #define DHE_ERROR_ALREADYOPEN	-12		// RETURN ERROR
    
    typedef struct{
    	WORD year;  
    	WORD month;  
    	WORD dayOfWeek;  
    	WORD date;  
    	WORD hour;  
    	WORD min;  
    	WORD sec;  
    	WORD milliseconds;
    }STIME;
    
    #endif
    

    das ist der unabgeänderte header.
    ich habe das struct am ende auskommentiert, da Qt WORD so direkt nicht zu kennen scheint, aber ich habe das struct auch noch nie gebraucht. (ich habe früher mal etwas mit dem gleichen SDK in VB geschrieben, nur konnte ich dort ein vorhandenes projekt ändern)
    ausserdem wie schon erwähnt die definition der funktion, denn die muss ja irgendwo definiert werden.

    hier ist noch der link zum SDK, wenn es weiter helfen sollte:
    http://www.dmxsoft.com/global/ftp/siudi_usb_developerkit.exe

    undefined reference heisst doch, dass der funktion body nirgends gefunden worde, oder?

    gruss
    jeremin



  • [gg]Nein heißt es nicht. Es heißt, dass der Compiler keine definition einer Funkion mit dem namen finden kann.

    Das SDK an sich ist echt schei**e. Da liefern die ne DLL und nen Header aber im Header ist die Methode nicht definiert. Und es gibt auch keine *.lib Datei zum linken. Die kommen echt aus der Delphi/VB ecke wo sowas scheinbar nicht notwendig ist

    In dem SDK gibt es auch ein c++ Beispiel (slmini2006). Dort verwenden die LoadLibrary um die DLL zur laufzeit zu laden.

    Da du ja schon die *.lib hast sollte folgende helfen, das zumindestens der Compiler zufrieden ist:

    Füge folgende Zeile dem Header der DLL hinzu:

    int DasUsbCommand(int, int, unsigned char*);
    

    Dann sollte der compiler die funktion kennen.



  • ok 🙂

    ich habs vor ein paar jahren mal geschafft, die dll in den borland c++ builder einzubinden, aber der steht mir jetzt nicht mehr zur verfügung (damals konnte ich ihn von der schule her nutzen), und es war schon damals ein drama 😞

    firefly schrieb:

    Da du ja schon die *.lib hast sollte folgende helfen, das zumindestens der Compiler zufrieden ist:

    Füge folgende Zeile dem Header der DLL hinzu:

    int DasUsbCommand(int, int, unsigned char*);
    

    Dann sollte der compiler die funktion kennen.

    tut er leider nicht, immer noch 4x

    C:\Users\Jeremin\Documents\QT\DMXTest-build-desktop\..\DMXTest\dmxtest.cpp:15: Fehler:undefined reference to `DasUsbCommand(int, int, unsigned char*)'

    und einmal:
    👎 Fehler:collect2: ld returned 1 exit status

    zur sicherheit mal noch den code aus der dmxtest.cpp, vielleicht hat sich dort noch nen fehler eingeschlichen:

    #include "dmxtest.h"
    #include "ui_dmxtest.h"
    
    #include "_DasHard2006.h"
    
    DMXTest::DMXTest(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::DMXTest)
    {
        ui->setupUi(this);
    
        int interfaceOpen;
        unsigned char dmxBlock[512];
    
        DasUsbCommand(DHC_INIT,0, NULL);
        interfaceOpen = DasUsbCommand(DHC_OPEN,0,0);
        ui->label->setText(QString(interfaceOpen));
    
        if (interfaceOpen>0){
            for(int i=0;i<512;i++)
                dmxBlock[i] = 0;
        }
    }
    
    DMXTest::~DMXTest()
    {
        delete ui;
    }
    

    ich habe gestern beim suchen noch entdeckt, dass Qt selber eine klasse QLibrary bereitstellt und die winAPI die im SDK verwende LoadLibrary funktion.
    der unterschied ist ja, dass bei diesen beiden lösungen die dll erst zur laufzeit geladen wird, im gegensatz zum bisher beschrittenen weg, aber hat das sonst noch auswirkungen?
    weil langsam überlege ich mir, dass anders zu lösen 😛
    oder hab ichs nur versaut, die .lib richtig zu erstellen, kann man die irgendwie überprüfen?

    danke für die mühe! 🙂



  • ups da lag ich wohl falsch. Wenn als letzte meldung

    ehler:collect2: ld returned 1 exit status

    kommt, dann ist es doch ein linker problem.

    hast du die erstellte lib ins C:\siudi\siudiUsb_developerkit\srcKopie\ verzeichnis kopiert?

    Ansonsten bleibt dir doch nichts anderes übrig als die DLL zur laufzeit "manuell" zu laden.

    Der Nachteil an der Methode ist, dass du dich selbst um das saubere entladen der DLL wieder kümmeern musst.



  • ja, die lib befindet sich dort.
    muss ich bei der namesvergabe irgendwas beachten?
    habe es bis jetzt mit DasHard2006.lib und libDasHard2006.lib versucht.

    sonst muss ich mir halt wirklich mal noch die syntax von QLibrary genauer ansehen.



  • die *.lib muss den gleichen namen haben wie die DLL.

    Kann es sein, dass du als qt-creator mit dem mingw compiler verwendest?

    eventuell hilft dir das hier eine passende import lib (*.lib) zu erstellen:
    http://www.mingw.org/wiki/CreateImportLibraries



  • ich benutze das standard qt IDE mit einem mingw verzeichnis, daher geh ich mal davon aus, dass ich mingw habe.

    gestern abend habe ich deinen link noch ausprobiert, hat leider nichts gebracht, obwohl es sehr vielverprechend aussah (es hat zb nen delphi dll beispiel)
    ausserdem habe ich noch folgenden weg versucht: klick mich
    das scheiterte aber schon daran, das reimp mir ein leeres .def file erstellte 😞

    heute morgen habe ich noch per google den beitrag gefunden:
    http://www.c-plusplus.net/forum/p719609#719609

    hab auch diese anleitung schritt für schritt befolgt, aber immernoch die gleichen fehler.

    zu guter letzt habe ich auch noch eine mail an die adresse im pdf des SDK's geschickt, mit der bitte um eine .lib oder eine .a, falls da nichts kommt, muss ich wohl oder übel den weg über Qlibrary wählen 😞

    nur noch eine frage:
    int DasUsbCommand(int command, int param, unsigned char *bloc);

    reicht das wirklich aus als definition?
    weil ich habe mein altes projekt mit dem c++ builder noch auf einem USB stick gefunden, da lautete die definition folgendermassen:

    extern "C" {
    	_declspec(dllimport) int DasUsbCommand(int command, int param, unsigned char *bloc);
    }
    

    im übrigen hatte ich im damaligen .def file noch ein @1 hinter dem funktions namen, was ich jetzt einfach nicht hinbekommen habe 🙂
    allerdings scheint es auch eine leicht andere dll zu sein, die jetztige ist ca 5x grösser 😮
    ich schau mal, ob ich die alte zum laufen kriege.



  • Das

    extern "C" {
        int DasUsbCommand(int command, int param, unsigned char *bloc);
    }
    

    ist elementar wichtig, da in C function-Symbole anders sind als in C++. Das _declspec(dllimport) kannst du auch weglassen.

    Kleiner Tipp noch. Vermeide Backslash. D.h.
    `

    LIBS += -L"C:/siudi/siudiUsb_developerkit/srcKopie" -lDasHard2006

    `



  • holzeimer schrieb:

    Das

    extern "C" {
        int DasUsbCommand(int command, int param, unsigned char *bloc);
    }
    

    ist elementar wichtig, da in C function-Symbole anders sind als in C++. Das _declspec(dllimport) kannst du auch weglassen.

    Kleiner Tipp noch. Vermeide Backslash. D.h.
    `

    LIBS += -L"C:/siudi/siudiUsb_developerkit/srcKopie" -lDasHard2006

    `

    oder mit $$quote(<text>) arbeiten, dann klappt es auch mit dem backslash



  • holzeimer schrieb:

    Das

    extern "C" {
        int DasUsbCommand(int command, int param, unsigned char *bloc);
    }
    

    ist elementar wichtig, da in C function-Symbole anders sind als in C++. Das _declspec(dllimport) kannst du auch weglassen.

    Kleiner Tipp noch. Vermeide Backslash. D.h.
    `

    LIBS += -L"C:/siudi/siudiUsb_developerkit/srcKopie" -lDasHard2006

    `

    habe ich beides ausprobiert, leider nix geholfen.

    dafür habe ich heute morgen eine antwort auf das mail erhalten:

    You don't need an lib file to use our dll with the Qt IDE.
    You can use it like in our Vc++ sample.

    tja, dann mach ichs halt mittels LoadLibrary, bzw. eher mittels QLibrary, ist mir sympathischer 🙂
    aber jetzt muss erst mal 2-3 wochen mit prüfungen verbringen, dann mache ich einen neuen versuch, diese dll einzubinden.

    auf jedenfall danke auch (vorallem firefly) für die hilfe 😃

    schönen abend
    jeremin



  • In dem Beispiel slmini.cpp ist doch alles drin was man braucht ?

    #include "_DasHard.h"
    
    HINSTANCE g_dasusbdll = NULL;
    typedef int (*DASHARDCOMMAND)(int, int, unsigned char*);
    DASHARDCOMMAND  DasUsbCommand = NULL;
    
    int HardDllOpen()
    {
    	g_dasusbdll = LoadLibrary("DasHard2006.dll");
    
    	if (g_dasusbdll)
    		DasUsbCommand  = (DASHARDCOMMAND)::GetProcAddress((HMODULE)g_dasusbdll, "DasUsbCommand");
    	if (DasUsbCommand)
    		return 1;
    	return 0;
    }
    
    int HardDllClose()
    {
    	if (g_dasusbdll!=NULL)
    		return	FreeLibrary(g_dasusbdll);
    	return 0;
    }
    
    int HardDllCommand(int command, int param, unsigned char *bloc)
    {
    	if (DasUsbCommand)
    		return (*DasUsbCommand)(command, param, bloc);
    	return 0;
    }
    

    Der Code sieht doch recht plausibel aus ...



  • also wenn ich das 1 zu 1 in Qt übernehmen kann, sag ich natürlich nicht nein 🙂
    aber ich werde mich erst in 2-3 wochen wieder dahinter setzen.

    gruss
    jeremin


Anmelden zum Antworten