Forum: PC-Programmierung Serielle schnittstelle in dll mit Qt implementieren


von Chr S. (chr_sch)


Angehängte Dateien:

Lesenswert?

Hi,

ich versuche in Qt eine dll zu schreiben, welche eine serielle 
Schnittstelle mit meinem Tiva C-Series Launchpad aufbaut.
Konkret soll die dll eigentlich nur 6 werte entgegen nehmen und diese in 
einer bestimmten Reihenfolge an den Mikrocontroller weitergeben.

Nachdem ich eine dll zum Test geschrieben hatte und diese einfach mit 
einem willkürlichen Programm testen wollte (aufruf der dll und übergabe 
von 6 Werten) bekomme ich einige Fehlermeldungen.

Diese Fehlermeldungen beziehen sich auf QSerialPort und lautet wie 
folgt:

Messwert_Zuordnung_DLL.obj:-1: Fehler: LNK2019: Verweis auf nicht 
aufgelöstes externes Symbol ""__declspec(dllimport) public: __cdecl 
QSerialPort::QSerialPort(class QObject *)" 
(_imp??0QSerialPort@@QEAA@PEAVQObject@@@Z)" in Funktion ""public: void 
__cdecl 
Messwert_Zuordnung_DLL::Messwert_zuordnung(double,double,double,double,d 
ouble,double)" 
(?Messwert_zuordnung@Messwert_Zuordnung_DLL@@QEAAXNNNNNN@Z)".

Im Anhang habe ich die .pro Dteien der dll und des Test Programmes, 
sowie die Header Dateien der dll und die Ausgabe des Debug.

Kann mir irgend jemand sagen wo der Fehler liegt ?

Gruß

: Verschoben durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dir scheint die Importlibrary zu fehlen, die Du verwenden musst, um die 
DLL pseudostatisch zu linken.

von Chr S. (chr_sch)


Lesenswert?

hey rufus,

was meinst du genau mit Importlibrary ?
Die .lib Datei von meiner erzeugten dll ?
Oder von QSerialPort ?

Gruß

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Den Symbolnamen zufolge scheint das QSerialPort selbst zu sein, wenn das 
in einer DLL daherkommt ...

Denn das ist recht eindeutig:

> __declspec(dllimport) public: __cdecl QSerialPort::QSerialPort(class
> QObject *)"

von Marvin (Gast)


Lesenswert?

Hi,

In der PRO Datei schon "QT += serialport" hnizugefügt ?

Bye

von Marvin (Gast)


Lesenswert?

Hi,

Jaja, wer zu schnell ließt...

Die QSerialPort.dll wird nicht mitgelinkt oder gefunden.

Bye

von Chr S. (chr_sch)


Lesenswert?

Hey,

ich habe in der pro Datei bei LIBS die Qt5SerialPort.lib hinzugefügt, 
welche ich in dem Ordner gefunden habe wo Qt installiert ist.
Nun bekomme ich aber Error Meldungen bezüglich der moc_qserialport.cpp 
Datei.

1.)..\debug\moc_qserialport.cpp:352: Fehler: C2027: Verwendung des 
undefinierten Typs "QSerialPortPrivate"
c:\users\christian\documents\build-dll_tester-desktop_qt_5_4_0_msvc2013_ 
64bit-debug\debug\../../dll_tester/qserialport.h(45):  Siehe Deklaration 
von 'QSerialPortPrivate'

2.)..\debug\moc_qserialport.cpp:352: Fehler: C2227: Links von 
"->_q_completeAsyncCommunication" muss sich ein Zeiger auf 
Klassen-/Struktur-/Union-/generischen Typ befinden.

Die weiteren Fehlermeldungen sind vom selben Typ.
Da die Datei aber nicht von mir stammt bin ich nicht sicher ob und wie 
ich diese verändern sollte oder ob einfach nur eine weitere Datei 
gelinkt werden muss.

gruß

: Bearbeitet durch User
von Freddy (Gast)


Lesenswert?

Ich habe in Deine Source noch nicht reingeguckt, aber welche QT Version 
nutzt Du?

Ich hatte ähnliche Probleme mit QT und dem DLL Export. Ich muss nochmal 
in den Sourcen nachsehen, aber achte drauf dass Du es nicht als 64 BIT 
kompilierst.
Du kannst Dir die DLL mal mit Depency Walker ansehen und prüfen ob die 
Funktionen exportiert wurde.

von Freddy (Gast)


Lesenswert?

Ich hatte damals auch vom MINGW auf den Microsoft Compiler umgestellt.
Aber ob es die Lösung war weiß ich nicht. Ich hatte extreme Probleme und 
lange probiert.

Dieses SUBSYSTEM:Windows,5.01 hatte etwas mit meinem Problem zu tun.
Möglicherweise war es aber auch das Problem, dass die DLL unter Win7 mit 
einem 64 Bit System erstellt wurde, ABER auch auf einem Win XP 32 Bit 
unter Matlab eingebunden werden musste und das nicht so lief.

Das Tool Depency Walker von Steve Miller und DLL Exp (nirsoft.net) haben 
mir jedoch geholfen um zu sehen wie weit meine Funktionen exportiert 
wurden.

Bei mir steht im .pro File noch folgendes:
1
win32 {
2
    QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01
3
    QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE,5.01
4
5
    DEFINES += _ATL_XP_TARGETING
6
    QMAKE_CFLAGS += /D _USING_V110_SDK71_
7
    QMAKE_CXXFLAGS += /D _USING_V110_SDK71_
8
    LIBS *= -L”%ProgramFiles(x86)%/Microsoft SDKs/Windows/7.1A/Lib”
9
    INCLUDEPATH += “%ProgramFiles(x86)%/Microsoft SDKs/Windows/7.1A/Include”
10
}
11
12
TEMPLATE = lib
13
#http://www.tripleboot.org/?p=423
14
# WIN XP
15
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Christian Schipp schrieb:
> Nun bekomme ich aber Error Meldungen bezüglich der moc_qserialport.cpp
> Datei.

Das sind aber keine Linker-, sondern Compilerfehler. Die werden nicht 
durch das Hinzufügen einer *.lib/*.a ausgelöst, der Compiler weiß 
überhaupt nichts von *.lib/*.a-Dateien.

von Chr S. (chr_sch)


Angehängte Dateien:

Lesenswert?

Ich benutze Qt Creator 3.3.0 basiert auf Qt 5.4.0 (MSVC 2010, 32 Bit).

Wenn ich bei den Kit-Einstellungen Desktop 32 Bit MSVC2012 OpenGL 
auswähle, bekomme ich den Fehler, dass kein Kompiler eingerichtet ist. 
Jedoch wenn ich bei den Kit Konfiguration einen Kompiler auswähle, wird 
dieser nicht übernommen.

Was genau ist denn das Problem mit 64 Bit ?

Ich habe die dll einmal mit dependency Walker geöffnet. Leider kann ich 
damit nicht viel anfangen. Aber es werden zwei Fehler gemeldet:
1.)Qt5Cored dll kann nicht gefunden werden
2.)Qt5SerialPort dll kann nicht gefunden werden

Im Anhang ist ein Screenshot.

Gruß

: Bearbeitet durch User
von Freddy (Gast)


Lesenswert?

1) und 2) sollten zusammen mit Deiner DLL im gleichen Verzeichnis 
liegen...

von Freddy (Gast)


Lesenswert?

kann es sein dass Deine Funktionen als c++ Funktionen exportiert werden?
Sieht im Depency Walker so aus.

Exportierst Du mit sowas in der Art:
#define MY_API extern "C" __declspec(dllexport)

MY_API int main (...);

von Chr S. (chr_sch)


Angehängte Dateien:

Lesenswert?

Ich habe die fehlenden dll Dateien bei die erzeugte dll Datei kopiert. 
Jedoch sind ncoh einige Dateien übrig welche ich nicht finden kann.
Ich habe noch einmal ein Screenshot beigefügt.

Meine global.h Datei sieht wie folgt aus:

#ifndef MESSWERT_ZUORDNUNG_DLL_GLOBAL_H
#define MESSWERT_ZUORDNUNG_DLL_GLOBAL_H

#include <QtCore/qglobal.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QWindow>

#if defined(MESSWERT_ZUORDNUNG_DLL_LIBRARY)
#  define MESSWERT_ZUORDNUNG_DLLSHARED_EXPORT Q_DECL_EXPORT
#else
#  define MESSWERT_ZUORDNUNG_DLLSHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // MESSWERT_ZUORDNUNG_DLL_GLOBAL_H

: Bearbeitet durch User
von chr_sch (Gast)


Lesenswert?

hat keiner eine Idee oder einen weiteren Hinweis ?

Gruß

von BobbyX (Gast)


Lesenswert?

Ich sehe in der PRO Datei des Testprograms keinen Verweis auf deine 
Dll... Nur der Pfad ist angegeben, die dll selbst nicht ....

von Chr S. (chr_sch)


Lesenswert?

Hi BobbyX,

die dll ist doch hier eingefügt:
LIBS += -L 
C:\..\DLL\build-Messwert_Zuordnung_DLL-Desktop_Qt_5_4_0_MSVC2013_64bit-D 
ebug\debug  -lMesswert_Zuordnung_Dll

Oder was müsste nach noch in der pro Datei stehen ?

Gruß

von BobbyX (Gast)


Lesenswert?

Wo denn? Die dll_tester.pro, die ich heruntergaladen habe:

#-------------------------------------------------
#
# Project created by QtCreator 2015-04-01T18:49:29
#
#-------------------------------------------------

QT       += core

QT       -= gui
QT       += serialport

TARGET = dll_tester
CONFIG   += console
CONFIG   -= app_bundle
INCLUDEPATH += 
C:\Users\Christian\Desktop\Studienarbeit\DLL\Messwert_Zuordnung_DLL
DEPENDPATH += 
C:\Users\Christian\Desktop\Studienarbeit\DLL\Messwert_Zuordnung_DLL
LIBS += 
C:\Users\Christian\Desktop\Studienarbeit\DLL\build-Messwert_Zuordnung_DL 
L-Desktop_Qt_5_4_0_MSVC2013_64bit-Debug\debug
TEMPLATE = app


SOURCES += main.cpp

HEADERS += \
    messwert_zuordnung_dll.h \
    messwert_zuordnung_dll_global.h\
    qserialport.h\
    qserialportglobal.h

von Chr S. (chr_sch)


Lesenswert?

Entschuldigung, mittlerweile habe ich da etwas geändert.

Heute habe ich noch eine weitere Änderung vorgenommen. Hier ist die 
aktuelle pro Datei des test Programms:
1
QT       += core
2
QT       += serialport
3
QT       -= gui
4
5
6
TARGET = dll_tester
7
CONFIG   += console
8
CONFIG   -= app_bundle
9
INCLUDEPATH += C:\Users\Christian\Documents\dll_tester
10
DEPENDPATH += C:\Users\Christian\Documents\dll_tester
11
LIBS += -LC:\Users\Christian\Documents\dll_tester-lMesswert_Zuordnung_Dll
12
TEMPLATE = app
13
14
15
SOURCES += main.cpp
16
17
HEADERS += \
18
    messwert_zuordnung_dll.h \
19
    messwert_zuordnung_dll_global.h
20
21
DISTFILES += \
22
    ../../Desktop/Studienarbeit/DLL/build-Messwert_Zuordnung_DLL-Desktop_Qt_5_4_0_MSVC2013_64bit-Debug/debug/Messwert_Zuordnung_DLL.dll

Nun bekomme ich folgende Fehlermeldungen:
1.)
main.obj:-1: Fehler: LNK2019: Verweis auf nicht aufgelöstes externes 
Symbol ""__declspec(dllimport) public: __cdecl 
Messwert_Zuordnung_DLL::Messwert_Zuordnung_DLL(void)" 
(_imp??0Messwert_Zuordnung_DLL@@QEAA@XZ)" in Funktion "main".

2.)
main.obj:-1: Fehler: LNK2019: Verweis auf nicht aufgelöstes externes 
Symbol ""__declspec(dllimport) public: void __cdecl 
Messwert_Zuordnung_DLL::uebergabe(double,double,double,double,double,dou 
ble)"  (_imp?uebergabe@Messwert_Zuordnung_DLL@@QEAAXNNNNNN@Z)" in 
Funktion "main".

Gruß

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Christian Schipp schrieb:
> LIBS +=
> -LC:\Users\Christian\Documents\dll_tester-lMesswert_Zuordnung_Dll

Bist Du Dir da mit der Syntax sicher?

Was soll da das -L?

Und wo steht da ein Dateiname? Heißt Deine Library 
"dll_tester-lMesswert_Zuordnung_Dll"?

von Chr S. (chr_sch)


Lesenswert?

Die Syntax habe ich von folgender Website übernommen:

https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application

Was genau das -L aber bedeutet, ist mir auch nicht klar.

Rufus Τ. Firefly schrieb:
> Und wo steht da ein Dateiname?

Mein Test Programm heißt dll_tester.
Meine dll Datei heißt Messwert_Zuordnung_DLL. Diese steht am Ende bei 
-l<Dateiname>

Gruß

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Christian Schipp schrieb:
> Meine dll Datei heißt Messwert_Zuordnung_DLL.

Das wird nicht der Dateiname Deiner DLL sein.

Fehlt da nicht noch ein .dll am Ende?


> Diese steht am Ende bei -l<Dateiname>

Und was hat das -l da verloren?

Sieh Dir mal im Makefile an, wie mit dem Makro LIBS umgegangen wird, und 
was für eine Kommandozeile für Deinen Linker dabei 'rauskommt.

Das sieht mir ziemlich kaputt aus.

von Chr S. (chr_sch)


Angehängte Dateien:

Lesenswert?

Wie gesagt ich habe diese Zeile laut der Dokumentation in dem Link 
geschrieben.

Ich habe nun auch einmal folgenden Ansatz versucht:
1
QLibrary library("Messwert_Zuordnung_DLL.dll");
2
    if (!library.load())
3
    qDebug() << library.errorString();
4
    if (library.load())
5
    qDebug() << "library loaded";
6
7
    library.resolve("uebergabe");

Dann muss man in der pro Datei nichts mehr schreiben.
Der Build läuft ohne Fehler.
Wenn ich meine dll einfach etwas über qDebug() auspucken lasse 
funktioniert es.

Aber wenn ich die Daten auf meinen Mikrocontroller weiterschicken will, 
kommt dort nichts an.

Ich habe die selben Konfigurationen von der seriellen Schnittstelle in 
einer GUI, wo es funktioniert. In der dll habe ich lediglich das 
connect() weggelassen und bei der Erstellung von:
serial = new QSerialPort()
konnte ich in den Klammern kein Parent Objekt angeben. Ist dies nötig ? 
Wenn ja wie mache ich das am besten, da ich hier kein Widget als Parent 
zur Verfügung habe.

Im Anhabg ist die cpp Datei in welcher ich die serielle Schnittstelle 
Konfiguriere und Aufrufe.
Gruß

von BobbyX (Gast)


Lesenswert?

Ich hoffe Du bist nur ein Hobby Programmierer :-) Obwohl schon ählich 
schlechten und fehlerhaften Code von "Profis" bei grossen deutschen 
Firmen gesehen habe :-) Auf die Schnelle sehe ich:

1. Du verwechselst offenbar das zur Verfügung stehen einer Dll zur 
Laufzeit mit zur Verfügung stehen einer Dll beim Linken.

2. Du vergleichst Flisskommazahlem mit Integer - total falsch.

3. Du instanzierst die Klasse QSerial jedesmal wenn du mit ihr was 
machst, ohne den Speicher wieder freizuheben - Speicherleck

4. Du verwendest exakt die gleichen Namen für globale Variablen und 
Namen der Funktionsargumente - sehr schlechte idee.

5. Vor dem Linker Argument -l muss ein Leezeichen sein....

Fange vielleicht mit etwas einfacherem an. Und ohne die Funktionalität 
in eine externe Dll auszulagern.

von Karl H. (kbuchegg)


Lesenswert?

Mal ganz schüchtern gefragt:
Die einzige Aufgabe ist es, eine serielle Schnittstelle aufzumachen und 
Werte weiterzugeben.
Ist dafür QT nicht ein bisschen Overkill?

von Steffen R. (steffen_rose)


Lesenswert?

Freddy schrieb:
> kann es sein dass Deine Funktionen als c++ Funktionen exportiert werden?

Ist dies bei QT nicht der Normalfall?

von Chr S. (chr_sch)


Lesenswert?

@ Karl Heinz:
Im Prinzip ist dies die einzige Funktion, das ist richtig.
Die dll soll im Endeffekt in einem Programm aufgerufen werden können um 
die Werte ohne Aufwand an den Mikrocontroller weiterzugeben.

Hast du einen besseren Vorschlag wie das zu realisieren ist ?
Die Idee ist, dass man nicht extra bei jedem Programm aufruf eine GUI 
aufmachen muss um die Werte zu übermitteln.

@BobbyX

zu 1.)
Was genau meinst du damit ?

zu2.)
Ich erwarte als Eingabe, lediglich eine 0 oder 1 was also keine Fehler 
generieren dürfte. Die verschiedenen Datentypen resultieren daraus, dass 
ich die Variablen enheitlich definieren wollte, damit es beim 
konvertieren zum senden gleich ist.

zu 3.)
Wie gebe ich den Speicher wieder frei ? Indem ich die Verbindung trenne 
?

zu 4.)
Die Variablen habe ich so benannt, da in diesen lediglich die Werte zum 
weitergeben gespeichert werden. Im Endeffekt werden ja keine Variablen 
deklariert in dem Programm, in welchem die dll eingesetzt werdne soll. 
Da werden die Werte einfach direkt an die Funktion übergeben. Dies habe 
ich nur als Gedankenstütze im Testprogramm gemacht.

zu 5.)

Ist erledigt ;)

Gruß

von BobbyX (Gast)


Lesenswert?

Chr S. schrieb:
> @ Karl Heinz:
> Im Prinzip ist dies die einzige Funktion, das ist richtig.
> Die dll soll im Endeffekt in einem Programm aufgerufen werden können um
> die Werte ohne Aufwand an den Mikrocontroller weiterzugeben.
>
> Hast du einen besseren Vorschlag wie das zu realisieren ist ?
> Die Idee ist, dass man nicht extra bei jedem Programm aufruf eine GUI
> aufmachen muss um die Werte zu übermitteln.
>
> @BobbyX
>
> zu 1.)
> Was genau meinst du damit ?
>
> zu2.)
> Ich erwarte als Eingabe, lediglich eine 0 oder 1 was also keine Fehler
> generieren dürfte. Die verschiedenen Datentypen resultieren daraus, dass
> ich die Variablen enheitlich definieren wollte, damit es beim
> konvertieren zum senden gleich ist.

Dann kannst du alles mit integer machen.

>
> zu 3.)
> Wie gebe ich den Speicher wieder frei ? Indem ich die Verbindung trenne
> ?

:-) Kauf dir ein gutes C++ Buch.


> zu 4.)
> Die Variablen habe ich so benannt, da in diesen lediglich die Werte zum
> weitergeben gespeichert werden. Im Endeffekt werden ja keine Variablen
> deklariert in dem Programm, in welchem die dll eingesetzt werdne soll.
> Da werden die Werte einfach direkt an die Funktion übergeben. Dies habe
> ich nur als Gedankenstütze im Testprogramm gemacht.

Du übergibst die globalen VAriablen NICHT an die Funktion in der Dll. 
Kauf dir ein gutes C++ Buch und fang ganz vorne an.

>
> zu 5.)
>
> Ist erledigt ;)
>
> Gruß

von Chr S. (chr_sch)


Lesenswert?

Ich sehe ein, dass mein Code Potential hat um besser zu werden.

Dennoch sollte das Programm erst einmal grundsätzlich funktionieren.
Das hängt momentan daran, dass mein Mikrocontroller mir keine Eingabe 
signalisiert.
Da genau der selbe Programmaufbau mit qDebug in der dll mir genau das 
ausgibt, was ich senden will, liegt das Problem an meinem Gebrauch von 
QSerialPort.
Wo liegt denn hierbei der Fehler ?

Gruß

von Chr S. (chr_sch)


Lesenswert?

Kann keiner helfen  ?

von Chr S. (chr_sch)


Lesenswert?

Kann jemand mit dem Rückgabewert -1073741510 etwas anfangen ?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das ist 0xC000013A.

Google mal nach diesem Wert, vielleicht hilft das ja. Wenn Du dann auch 
noch den Kontext angibst, in dem der Wert auftaucht (wenn es ein 
Rückgabewert ist, wird ja der Rückgabewert irgendwovon sein ...), hast 
Du mehr Chancen, etwas zu finden.

von Chr S. (chr_sch)


Angehängte Dateien:

Lesenswert?

Der Rückgabewert resultierte daraus, dass ich die Konsole einfach 
geschlossen habe.

Ich habe versucht mit :  qDebug()<< serial->errorString()
rauszufinden, wo der Fehler liegt.
Leider war die Ausgabe "Unknown Error".

Ich habe meine dll Datei sowie das Testprogramm noch einmal angehängt in 
der Hoffnung, dass doch noch jemandem auffällt wo der Fehler liegt.

Die Dateien sind von den Variablen her und vom Code nicht besonders 
schön oder effektiv.

Mir geht es hier darum die Funktion sicherzustellen.

: Bearbeitet durch User
von Christoph M. (chrito)


Lesenswert?

Bei mir kam der gleich Fehler...

Verweis auf nicht
aufgelöstes externes Symbol

...und das Problem war ein Umlaut im Projektpfad :)

Schade, dass hier nicht alles schon mit UTF8 funktioniert!

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.