QtCreator Dll einbinden
-
ja, die header-datei ist eingebunden, die konstanten werden auch erkannt.
ich habe aber grad gemerkt, dass ich gestern was falsches geschrieben habe:wenn ich im headerfile die funktion definiere, bekomme ich 4 mal folgenden fehler:
C:\Users\Jeremin\Documents\QT\DMXTest-build-desktop\..\DMXTest\dmxtest.cpp:16: Fehler:undefined reference to `DasUsbCommand(int, int, unsigned char*)'
und nicht 4 mal:
C:\Users\Jeremin\Documents\QT\DMXTest-build-desktop\..\DMXTest\dmxtest.cpp:15: Fehler:'DasUsbCommand' was not declared in this scope
dieser fehler tritt nur auf, wenn ich die funktion nicht definiere (was ja irgendwie logisch ist, ich weiss nicht, warum ich gestern nicht selbst drauf gekommen bin :S)
sorry dafür
das heisst wohl, dass er immernoch nicht weiss, wo er die funktion der dll finden kann, oder?
-
?? 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.exeundefined 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 statuszur 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 erstellteheute morgen habe ich noch per google den beitrag gefunden:
http://www.c-plusplus.net/forum/p719609#719609hab 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