serial port in dll



  • Hi at all,

    I want to write a dll file , using a serial port.
    I will describe what the dll should do:
    I call the function of the dll in a measurement programm. The function should accept 6 initial values, which should be send to a microcontroller. So in the dll I want to use the QtSerialPort and send the values to my microcontroller.

    I wrote a dll but when I try to run it in a test programm I get a lot of errors:
    " LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""__declspec(dllimport) public: bool __cdecl QSerialPort::setDataBits(enum QSerialPort::DataBits)" (_imp?setDataBits@QSerialPort@@QEAA_NW4DataBits@1@@Z)" in Funktion ""public: void __cdecl Messwert_Zuordnung_DLL::Messwert_zuordnung(double,double,double,double,double,double)" (?Messwert_zuordnung@Messwert_Zuordnung_DLL@@QEAAXNNNNNN@Z)"."

    Here is my dll code:
    <
    #include "messwert_zuordnung_dll.h"
    #include <iostream>
    #include <string>
    #include <math.h>
    #include <QDebug>
    #include <QtCore/QCoreApplication>
    #include <Windows.h>
    #include <QtSerialPort/QSerialPort>
    #include <QtCore/QDebug>

    QSerialPort *serial;

    void Messwert_Zuordnung_DLL::Messwert_zuordnung(double messmeth, double messint, double bauteillaenge, double interpol, double anz_messungen, double abs_messungen)
    {
    //Configuration of the serial port
    serial = new QSerialPort;

    //+++++++++++++++++++++++++++++++++++
    //+++++++++++++++++++++++++++++++++++
    //Adapt the COM-Port !
    
    serial->setPortName("COM12");
    
    //+++++++++++++++++++++++++++++++++++
    //+++++++++++++++++++++++++++++++++++
    
    
    serial->setBaudRate(QSerialPort::Baud115200);
    serial->setDataBits(QSerialPort::Data8);
    serial->setParity(QSerialPort::NoParity);
    serial->setStopBits(QSerialPort::OneStop);
    serial->setFlowControl(QSerialPort::SoftwareControl);
    
    
    serial->open(QIODevice::ReadWrite);
    
    
         if (messmeth == 1){
    
    
            //Conversion to send (requiered by the send-> function) 
    
    
            QByteArray messint_s = QByteArray::number(messint);
            QByteArray bauteillaenge_s = QByteArray::number(bauteillaenge);
            QByteArray interpol_s = QByteArray::number(interpol);
            QByteArray anz_messungen_s = QByteArray::number(anz_messungen);
            QByteArray abs_messungen_s = QByteArray::number(abs_messungen);
    
            //Sending the variables
            serial->write("1");
            serial->write("\n");
    
            serial->write(bauteillaenge_s);
            serial->write("\n");
    
            serial->write(messint_s);
            serial->write("\n");
    
            serial->write(interpol_s);
            serial->write("\n");
    
            serial->write(anz_messungen_s);
            serial->write("\n");
    
            serial->write(abs_messungen_s);
            serial->write("\n");
    

    Maybe I have to initiate the serial port in an other way ? Can anybody help me ?

    regards



  • This post is deleted!


  • Can you post your pro file?

    Do you have this line in it?

    QT += serialport



  • Hi @chr_sch,

    could you clarify if your problem is to build the dll itself, or to include the dll in another project?



  • @t3685
    that´s my pro file:

    TARGET = Messwert_Zuordnung_DLL
    TEMPLATE = lib
    
    QT += serialport
    QT += core
    QT -= gui
    
    DEFINES += MESSWERT_ZUORDNUNG_DLL_LIBRARY
    
    SOURCES += messwert_zuordnung_dll.cpp
    
    HEADERS += messwert_zuordnung_dll.h\
            messwert_zuordnung_dll_global.h
    
    
    unix {
        target.path = /usr/lib
        INSTALLS += target
    }
    

    serialport is added.

    @sneubert:

    the dll builds without a problem. But I am not shure that it works correctly in the way I created it.
    In the test programm I added the .h and global .h file and set the reference to the dll file.
    Here is the pro file from my test program:

    QT       += core
    
    QT       -= gui
    QT       += serialport
    
    TARGET = dll_tester
    CONFIG   += console
    CONFIG   -= app_bundle
    LIBS += "C:\Users\Christian\Documents\build-dll_tester-Desktop_Qt_5_4_0_MSVC2013_64bit-Debug\debug\Messwert_Zuordnung_DLL.obj"
    TEMPLATE = app
    
    
    SOURCES += main.cpp
    
    HEADERS += \
        messwert_zuordnung_dll.h \
        messwert_zuordnung_dll_global.h \
        qserialport.h \
        qserialportglobal.h
    


  • At first glance it seems you are not linking to your library properly. Have a look at the link below for an example on how to link to a library.

    https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application



  • @t3685

    I changed a few things in my .pro file according to the instructions in the link you send.
    Namely I changed the following three things

    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_DLL-Desktop_Qt_5_4_0_MSVC2013_64bit-Debug\debug

    But the Problem stayed ! The error refers to the QSerialPort I used.
    I tried to include the DEPENDPATH and INCLUDEPATH where the qserialport.h file is in the Qt folder and added the qserialport.h file to the Header but no succes.

    Any other ideas ?

    regards



  • @chr_sch

    Hello,

    I think you still have an error in your pro file. The correct syntax to link to a library is

    LIBS += -L<path to your dll> -l<name of your dll>

    In your pro file you don't have the -l and -L. Please follow the instructions in the wiki more closely



  • @t3685

    I changed it :
    LIBS += -L C:\Users\Christian\Desktop\Studienarbeit\DLL\build-Messwert_Zuordnung_DLL-Desktop_Qt_5_4_0_MSVC2013_64bit-Debug\debug -lMesswert_Zuordnung_Dll

    Still getting the error.

    regards



  • @chr_sch

    Hi,

    Did you put a export macro in your class like explained in the wiki and on this page:

    http://doc.qt.io/qt-5/sharedlibrary.html

    Greetings,

    t3685



  • @t3685
    I added the Qt5SerialPort.lib, found somewhere in the Qt intalling folder, in the pro file under LIBS.
    This generated some new errors refers to the moc_qserialport.cpp like this:

    1.)..\debug\moc_qserialport.cpp:352: Fehler: C2027: using
    undefined Typ "QSerialPortPrivate"
    c:\users\christian\documents\build-dll_tester-desktop_qt_5_4_0_msvc2013_
    64bit-debug\debug../../dll_tester/qserialport.h(45): Declaration
    of 'QSerialPortPrivate'

    2.)..\debug\moc_qserialport.cpp:352: Fehler: C2227: to the left of
    "->_q_completeAsyncCommunication" must be an pointer to an class/strucktur/union/generic type

    regards



  • @chr_sch

    You don't need to add Qt5SerialPort.lib.
    The error you are getting is that the linker cannot find the implementation of "Messwert_Zuordnung_DLL::Messwert_zuordnung".
    Like I said this is either due to:

    a) incorrectly linking to your dll
    b) not declaring the function/class for export

    Both situations are explained in:

    http://doc.qt.io/qt-5/sharedlibrary.html

    So if the problem persist, please make sure that both conditions are fulfilled exactly as described in the link.



  • This is my header file:

    #if defined(MESSWERT_ZUORDNUNG_DLL_LIBRARY)
    #  define MESSWERT_ZUORDNUNG_DLLSHARED_EXPORT Q_DECL_EXPORT
    #else
    #  define MESSWERT_ZUORDNUNG_DLLSHARED_EXPORT Q_DECL_IMPORT
    #endif
    
    class MESSWERT_ZUORDNUNG_DLLSHARED_EXPORT Messwert_Zuordnung_DLL
    {
    
    public:
        Messwert_Zuordnung_DLL();
    
        void uebergabe(double messmeth,double messint, double bauteillaenge, double interpol, double anz_messungen, double abs_messungen);
    };
    

    Therefore I think it is like mentioned in the link.

    The linking to my dll consists of the following points:
    -include the header files in my tets programm (copy them in the same direction)
    -DEPENDPATH/INCLUDEPATH path to the folder where the .dll/.obj/.lib files are
    -LIBS -L Path to dll -lname of dll
    -HEADER name the headers to include

    So i followed the description in the link but I just cant see where my faults are ?!
    Should I send you my files ?

    regards


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Did you re-run qmake after adding QT += serialport ?



  • @SGaist

    Yes I run qmake.
    I tried to set the paths to the folder where my test program is.
    Now I get the error:
    main.obj:-1: Fehler: LNK2019:unresolved external symbol""__declspec(dllimport) public: void __cdecl Messwert_Zuordnung_DLL::uebergabe(double,double,double,double,double,double)" (_imp?uebergabe@Messwert_Zuordnung_DLL@@QEAAXNNNNNN@Z)" in function "main".

    regards


  • Lifetime Qt Champion

    Did you check that you are doing the property symbol exporting ? Define name for activating the export macro etc. ?



  • @chr_sch

    Do you this macro: MESSWERT_ZUORDNUNG_DLL_LIBRARY defined in the pro file of your library?



  • I choose to use QLibrary instead of implementing the dll by myself. Therefore I used the following code in my main.cpp:

     QLibrary library("Messwert_Zuordnung_DLL.dll");
        if (!library.load())
        qDebug() << library.errorString();
        if (library.load())
        qDebug() << "library loaded";
    
        library.resolve("uebergabe");
    

    I am not really shure, that this is the proper use of QLibrary but it builds without an error.
    So I think it might work.
    If my dll gives simply the value in qDebug() out which I write in the dll function in my test programm it works.
    But if I try to establish a serial connection, my microcontroller does not recognize a input. So there is a fault in the use of the QSerialPort in my code. The same code is used in a GUI where it works. I only did not use the connect() function and in the definition of my port serial* = new QSerialPort (this) I didn´t write this. Because I have no parent object here. Do I have to establish a QObject for this ? Or is there any other problem with the use of QSerialPort in a dll ?

    Here is my code:

    QSerialPort *serial;
     serial = new QSerialPort();
    
    
        //+++++++++++++++++++++++++++++++++++
        //+++++++++++++++++++++++++++++++++++
        //COM-Port !
    
        serial->setPortName("COM12");
    
        //+++++++++++++++++++++++++++++++++++
        //+++++++++++++++++++++++++++++++++++
    
    
        serial->setBaudRate(QSerialPort::Baud115200);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::SoftwareControl);
    
    
        serial->open(QIODevice::ReadWrite);
    
    
                //conversion of the variables for the use of the send function
    
    
                QByteArray messint_s = QByteArray::number(messint);
                QByteArray bauteillaenge_s = QByteArray::number(bauteillaenge);
                QByteArray interpol_s = QByteArray::number(interpol);
                QByteArray anz_messungen_s = QByteArray::number(anz_messungen);
                QByteArray abs_messungen_s = QByteArray::number(abs_messungen);
    
                //Sending the variables to my microcontroller
                serial->write("1");
                serial->write("\n");
    

    regards


  • Lifetime Qt Champion

    Was it dll_tester that you failed to link ? If so, you were not linking to the library.

    You need to delete serial by hand when not using it anymore otherwise you'll be leaking memory



  • @SGaist
    I don´t know where my fault was. I think it was some linking problem but I don´t know how to solve so I use QLibrary.

    Ok you mean that I have to close the serialport at the end of the dll ?
    Can you see any other fault? Because the serial connection is not working .


  • Lifetime Qt Champion

    You have to delete serial. IIRC that should also close it.

    In any case, you should recheck your project and make it link properly to your library. Using QLibrary as a workaround is not the proper thing to do.



  • @SGaist
    Yes but this should only be a test program to see if the dll works correctly. In the end the dll is used in an othe context, so I want to focus on the function of the dll. Alltough it would be nice to know where my fault was. But I did everything like in the description in the links above nothing works, so I have to move on to loos not more time.

    But why doesn´t works my serial connection ? That is in the moment my biggest problem.
    Do I have to create a QObject as parent when I don´t have a window as parent ?
    Is the connect function necessary ?
    I thought the use is only to refer the connection fe to a button. But in a dll it should be unnecessary.

    Is this maybe the troublemaker?


  • Lifetime Qt Champion

    Why it doesn't work ? I can't tell, that's Crystal Ball debugging at this point. However, you don't check that that your device opened successfully



  • @SGaist

    Yeah that´s kind of diffucult. But I need help because I dont´t know how to figure out where my problem is.
    I tried in a working serial port GUI to delete the connect() function and the "this" in new QSerialPort(this). It is still working. So the code should work.

    With : if(!serial->open(QIODevice::ReadWrite)){qDebug()<<"Connection failed"}. I figured out, that the connection is not opened.

    I get the return value: -1073741510. Knows anybody what this means?

    regards


  • Lifetime Qt Champion

    Your application has been aborted e.g. you stopped it brutally.

    Did you check the returned error ? What is it ?



  • @SGaist
    How to check the error ? My program runs without showing an error. But there has to be one because the serial connection can´t be opened.

    I tried to use : qDebug()<< serial->errorString();
    But the output was "Unkown error".


  • Lifetime Qt Champion

    Ok, then just create on minimal application that opens that serial port and tries to write to / read from it. That will at least help check that your serial port is working correctly



  • @SGaist
    My first project was a GUI that communicates with that serial port.
    This still works fine. I used the same code to implement the serial connection in the dll file. Only the parent object, if i create the new QSerialPort, in thr parenthesis is empty. And i do not use the connect () function. If i change the code in the GUI it still works.
    In the GUI as well as in the dll the serial connection us only used to send a few variables to a microcontroller. So it should be a minimal requirement to the serial. Maybeit it is not possible to write a dll that opens a serial port at runtime ?


  • Lifetime Qt Champion

    There's no such restriction.

    Since you had trouble with the library in the first place, the next step is to create a minimal library that will provide some dummy function and link to it. Don't use QLibrary to load, just make your application link to it properly.



  • @SGaist

    Ok I just tried to create a new one.
    My steps:
    *Qt Creator -> new -> dll
    *add a dummy function under public in my header
    *dummy function in the cpp file: qDebug() << dll works

    *create a new console application
    *right click add existing file: mark the two header files from my dll
    *set the paths: -> INCLUDEPATH += folder from my dll where the headers are
    ->DEPENDPATH+= same folder as above
    ->LIBS+= -Ldebug folder of my dll file -lname of my dll file
    *copy the dll in the debug folder of the test program
    *in the test programm i add in the cpp file:
    -> include the header
    ->create new object
    -> call the function from the dll

    All works well. But if I try to pass an integer through the function to my dll I get an unresolved symbol error.
    After I changed my dll I re-build it and changed the copied files through the new ones.


  • Lifetime Qt Champion

    Can you show the code where you pass that integer ?



  • @SGaist

    In the dll i specified the following function:
    -header
    public:
    void Test(int a);

    -cpp
    qDebug()<< a;

    in the Test program:
    int b=1;
    MyLib c ;
    c.test(b);

    The exact error message is:
    main.obj:-1: Error: LNK2019: unresolved symbol ""__declspec(dllimport) public: void __cdecl MyLib::Test(int)" (_imp?Test@MyLib@@QEAAXH@Z)" in function "main".


  • Lifetime Qt Champion

    You are not exporting Test properly



  • @SGaist
    How to do so ?
    Where is my fault ?


  • Lifetime Qt Champion

    You have a nice explanation in the Creating shared libraries chapter of Qt's documentation



  • @SGaist
    I red this chapter already and my header files as well as the pro file are as specified in the explanation:
    dll.h:

    #ifndef MESSWERT_ZUORDNUNG_DLL_H
    #define MESSWERT_ZUORDNUNG_DLL_H
    
    #include "messwert_zuordnung_dll_global.h"
    
    MESSWERT_ZUORDNUNG_DLLSHARED_EXPORT void Test(int a);
    
    class MESSWERT_ZUORDNUNG_DLLSHARED_EXPORT Messwert_zuordnung_dll
    {
    
    public:
        Messwert_zuordnung_dll();
    
        void Test(int a);
    };
    
    #endif // MESSWERT_ZUORDNUNG_DLL_H
    

    dll_global.h

    #ifndef MESSWERT_ZUORDNUNG_DLL_GLOBAL_H
    #define MESSWERT_ZUORDNUNG_DLL_GLOBAL_H
    
    #include <QtCore/qglobal.h>
    
    #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
    

    I cant see a big difference.


  • Lifetime Qt Champion

    Following your various piece of code, you don't have any class called MyLib containing Test(int) nor any namespace containing such a function



  • @SGaist
    I changed the name, because the actual is a bit long. My class is Messwert_zuordnung_dll.
    The function for the export is Test.


  • Lifetime Qt Champion

    Ok so your

    MyLib c;
    c.test(b);
    

    should rather be:

    Messwert_zuordnung_dll mzd;
    mzd.Test(b);
    

    correct ?

    So, when you are building your dll, do you get both the dll and corresponding lib file ?



  • @SGaist
    Yes that´s correct. Sorry at this point for the confusion with the names.

    Yes the build creates a .dll/.lib and .obj file.
    At the beginning I had some trouble with the link I set as dependent path and libs in the pro file because there where a space in it. The error said "could not open .obj" so maybe it the program tries to open the .obj instead of the .dll ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.