Forum: PC-Programmierung "nackte" DLL einbinden (Qt)


von Ben j. (scarab)


Lesenswert?

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
1
win32 { LIBS += -LD:\temp\Qt\test1\Olib -lPCSGU250 }

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
void Start_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()'
3
collect2: ld returned 1 exit status

Ich vermute das meine Header falsch ist, oder?

von Peter II (Gast)


Lesenswert?

man kann auch dlls dynamisch laden, dann braucht man keine lib und 
keinen header datei.


http://msdn.microsoft.com/en-us/library/ms810279.aspx

von Εrnst B. (ernst)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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)

von Klaus W. (mfgkw)


Lesenswert?

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.

von Udo S. (urschmitt)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Ben j. (scarab)


Lesenswert?

mit extern "C" hat es geklappt :)

Danke!

von Udo S. (urschmitt)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Udo S. (urschmitt)


Lesenswert?

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.

von Sven P. (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Sven P. (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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?

von Sven P. (Gast)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.