Hallo,
ich versuche eine .dll (von dem PC-Oszilloskope PCSGU250) in ein
Qt-Projekt einzubinden.
In der Zip vom Hersteller befindet sich keine .a .lib .def oder .h
sondern nur die .dll, eine .bit und ein paar Beispiele für delphi und
VS.
ich habe mir schon die .def erstellt mittels pexports.
Dannach hab ich die .lib erstellt mit dem tool von VisualStudio 2010.
Eingebunden habe ich das ganze in Qt mit
wie geht es jetzt weiter?
wenn ich versuche eine Funktion aus der DLL aufzurufen kommt beim
compilieren der Fehler:
1
D:\temp\Qt\test1-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK__Debug\..\test1\main.cpp:10: Fehler:'Start_PCSGU250' was not declared in this scope
Erstelle ich mir eine Header mit
1
voidStart_PCSGU250(void);
kommt:
1
debug/main.o: In function `Z5qMainiPPc':
2
D:\temp\Qt\test1-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK__Debug/../test1/main.cpp:11: undefined reference to `Start_PCSGU250()'
Wenn's ein QT-Projekt ist, bietet sich zum dynamischen Laden natürlich
QLibrary an:
http://qt-project.org/doc/qt-4.8/qlibrary.html
Damit wird das sogar noch halbwegs Plattformunabhängig, was wohl mangels
einer PCSGU250-DLL für MacOS/Linux egal ist.
Peter II schrieb:> man kann auch dlls dynamisch laden, dann braucht man keine lib und> keinen header datei.
Einen Header braucht man trozdem. Da sind dann eben Zeiger auf
Funktionen deklariert statt der Funktionen selbst. also ist damit nichts
gewonnen. Man hat im Gegenteil noch den Zusatz-Aufwand, diese Pointer
alle einzeln initialisieren zu müssen.
Ben jamin schrieb:> Ich vermute das meine Header falsch ist, oder?
Ich gehe mal davon aus, daß die DLL dir ein C-Interface gibt, und da
fehlt dir das extern "C". Zusätzlich gibt es unter Windows auch für C
unterschiedliche Aufrufkonventionen, und du mußt evtl. die richtige
explizit angeben. Das hängt dann ggf. noch vom Compiler ab. Siehe
http://wyw.dcweb PUNKT cn/stdcall.htm
(PUNKT bitte durch . ersetzen - das Forum wollte es mich anders nicht
posten lassen, da das angeblich Spam sei)
Es könnte hilfreich sein, mit einem Tool wie DUMPBIN die Namen der in
der Lib bzw. DLL exportierten Namen zu erfahren.
Je nach den gefundenen Namen kann man dann auf die Aufrufkonvention
schließen (name mangling von C++, oder _ vorangestellt und/oder
Parameterlänge mit im Namen verschlüsselt).
Ansonsten halt man in den vorhandenen Projekten spicken, was da so
deklariert ist.
Rolf Magnus schrieb:> Peter II schrieb:>> man kann auch dlls dynamisch laden, dann braucht man keine lib und>> keinen header datei.>> Einen Header braucht man trozdem. Da sind dann eben Zeiger auf> Funktionen deklariert statt der Funktionen selbst. also ist damit nichts> gewonnen. Man hat im Gegenteil noch den Zusatz-Aufwand, diese Pointer> alle einzeln initialisieren zu müssen.
Den Header braucht man auf jeden Fall wegen den Funkionsdeklarationen.
Dynamisches Laden hat trotzdem seine Vorteile speziell dann wenn man
nicht wissen kann ob die DLL auf jedem installierten System zur
Verfügung steht. Ist sie statisch eingebunden kann man das Programm ohne
die DLL nicht starten.
Udo Schmitt schrieb:> Den Header braucht man auf jeden Fall wegen den Funkionsdeklarationen.
nö, den Prototype kann kan gleich in die C datei schreiben. Es gibt auch
keinen offizellen Header z.b. für die capi20.dll. Es gibt nur eine
beschreibung der Funktionen und von den Parametern.
Peter II schrieb:> Udo Schmitt schrieb:>> Den Header braucht man auf jeden Fall wegen den Funkionsdeklarationen.>> nö, den Prototype kann kan gleich in die C datei schreiben.
Natürlich kann man das auch tun, aber das kann man auch, wenn man an die
DLL dranlinkt.
Peter II schrieb:> nö, den Prototype kann kan gleich in die C datei schreiben.
Pfuschlösung, dann schreibt man sich für die DLL einen eigenen Header
den man einbindet.
Meine Meinung
Ben jamin schrieb:> mit extern "C" hat es geklappt :)
Ok, war also klassische C lib. Prima wenn das Problem gelöst ist.
Udo Schmitt schrieb:> Pfuschlösung, dann schreibt man sich für die DLL einen eigenen Header> den man einbindet.> Meine Meinung
nein, wenn ich mir einen eigenen C++ Wrapper schreibe, dann hat der
Prototype nicht in der Headerdatei verloren, er soll ja von niemand
anderen genutzt werden.
Peter II schrieb:> nein, wenn ich mir einen eigenen C++ Wrapper schreibe, dann hat der> Prototype nicht in der Headerdatei verloren,
Ja WENN ich einen C++ wrapper schreibe, dann stimme ich dir zu.
Bis zum letzen Posting war aber nicht von wrappern die Rede sondern von
einer einfachen Bibliothek.
Und die wird ggf. mehrfach und in mehreren Sourcen genutzt.
Peter II schrieb:> Udo Schmitt schrieb:>> Pfuschlösung, dann schreibt man sich für die DLL einen eigenen Header>> den man einbindet.>> Meine Meinung>> nein, wenn ich mir einen eigenen C++ Wrapper schreibe, dann hat der> Prototype nicht in der Headerdatei verloren, er soll ja von niemand> anderen genutzt werden.
Und selbst dann zwingt dich ja niemand, diesen Header ebenfalls zu
exportieren. Der Header der C-Bibliothek muss ja nicht derselbe sein,
den du für den C++-Wrapper anbietest.
Sven P. schrieb:> Und selbst dann zwingt dich ja niemand, diesen Header ebenfalls zu> exportieren. Der Header der C-Bibliothek muss ja nicht derselbe sein,> den du für den C++-Wrapper anbietest.
header nutzt man nur wenn mehr als eine C quelle die infos braucht, wenn
es nur ein einer C quelle verwendet wird, dann macht es überhaupt keinen
sinn es erst in eine header datei zu schreiben.
Peter II schrieb:> Sven P. schrieb:>> Und selbst dann zwingt dich ja niemand, diesen Header ebenfalls zu>> exportieren. Der Header der C-Bibliothek muss ja nicht derselbe sein,>> den du für den C++-Wrapper anbietest.>> header nutzt man nur wenn mehr als eine C quelle die infos braucht, wenn> es nur ein einer C quelle verwendet wird, dann macht es überhaupt keinen> sinn es erst in eine header datei zu schreiben.
Header nutzt man in erster Linie, im Quelltext zu strukturieren. Den
Compiler interessieren Header nicht, der bekommt davon garnichts mit.
Insofern ist es durchaus sehr sinnvoll, Prototypen in einen Header zu
verfrachten.
Sven P. schrieb:> Header nutzt man in erster Linie, im Quelltext zu strukturieren. Den> Compiler interessieren Header nicht, der bekommt davon garnichts mit.
nein, sie sind die die Krücke damit man die C datei unabhängig
voneinander compielen kann. Es macht sonst überhaupt sinn, informationen
an 2 verschienden stelle zu pfegen.
Oder legst du etwas eine header datei an, wo du main deklarierst?
Peter II schrieb:> Sven P. schrieb:>> Header nutzt man in erster Linie, im Quelltext zu strukturieren. Den>> Compiler interessieren Header nicht, der bekommt davon garnichts mit.>> nein, sie sind die die Krücke damit man die C datei unabhängig> voneinander compielen kann.
Du vergisst völlig den Aspekt der Dokumentation.
> Es macht sonst überhaupt sinn, informationen> an 2 verschienden stelle zu pfegen.
Es ist aber sinnvoll, eine Informationsmege zu gliedern. Und wenn ich
einen C++-Wrapper für irgendeine C-Bibliothek schreibe, dann gehören die
Prototypen dieser C-Bibliothek einfach nicht in die Quelle meines
Wrappers. Es ist nämlich eigentlich Aufgabe des Bibliotheksautors, die
Prototypen bereitzustellen.
Wenn du einen solchen Wrapper schreibst, pflegst du mit deiner Variate
schon (unnötigerweise, wie du richtig erkannt hast) doppelt. Du hast die
Prototypen ja aus der Bibliothek abgepinnt und in deinen Quelltext
übertragen. Da wäre ein Header für die Bibliothek sinnvoller. Und selbst
wenn du dir den schnell selbst schreibst, weil der Autor der Bibliothek
keinen mitliefert, hast du praktisch keinen Mehraufwand. Dafür hast du
aber einen Header, denn du nutzen kannst, wenn du die Bibliothek später
nochmal in anderem Zusammenhang (z.B. ohne den Wrapper) brauchst.
Kosten/Nutzen.
> Oder legst du etwas eine header datei an, wo du main deklarierst?
Ja. Aber nicht dem Programmeinsprung wegen.