As dynamic libraries to use class variables?



  • Hi.
    As dynamic libraries to use class variables?
    I have a dynamic library function

    void StrategyCod2()
    {
        qDebug()<<"Library work2"<<NBar;
    }
    

    NBar is a variable of the MainWindow class of the main application.
    Please tell me how StrategyCod2 function() use variable NBar?


  • Lifetime Qt Champion

    Hi,

    Make it a parameter of StrategyCod2



  • @SGaist said in As dynamic libraries to use class variables?:

    Make it a parameter of StrategyCod2

    But these parameters about 20. Is there another option?


  • Lifetime Qt Champion

    Since you are showing only a qDebug statement I would say do it directly in the class that is concerned. Otherwise explain what the methods should really do with these variables.



  • The function of the strategy calculates the functions and variables of the class.
    Because I need to pass variables to the function library.


  • Qt Champions 2016

    @Mikee
    use a class struct to hold the variables and
    pass that to library function

    mydata.h

    class mydata {
    public:
    int x;
    QString name;
    float NBar;
    }


    #include "mydata.h"
    void StrategyCod2(mydata & data)
    {
    qDebug()<<"Library work2"<<data.NBar;
    }



  • I use class

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include "qcustomplot.h"
    #include <QFile>  
    #include <QDebug>
    #include <QByteArray> 
    #include <QString> 
    #include <QVector>
    #include <QTextStream>
    #include <QStringList>
    #include <iostream>
    #include <QtConcurrent/QtConcurrent>
    #include <QMutex>
    
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
      long long NBar;
    

    When i do

    #include <C:\\Qt\project\\MyCandleSrick\\mainwindow.h>
    

    Appeared error: no files

    #include <QMainWindow>
    #include "qcustomplot.h"
    #include <QFile>  
    #include <QDebug> 
    #include <QByteArray> 
    #include <QString> 
    #include <QVector>
    #include <QTextStream>
    #include <QStringList>
    #include <iostream>
    #include <QtConcurrent/QtConcurrent>
    #include <QMutex>
    

  • Qt Champions 2016

    @Mikee
    I dont know what "error: no files" is or means or what happens.
    where do you do

    #include <C:\\Qt\project\\MyCandleSrick\\mainwindow.h> ?
    also should be
    #include "C:\\Qt\project\\MyCandleSrick\\mainwindow.h"
    


  • In the library :

    #include "C:\\Qt\project\\MyCandleSrick\\mainwindow.h"
    

    error:
    C:\Qt\project\MyCandleSrick\mainwindow.h:4: error: QMainWindow: No such file or directory


  • Qt Champions 2016

    @Mikee
    Well what is on line 4 in mainwindow.h ?
    It says it cant find what ever you include there.


  • Qt Champions 2016

    Hi
    You should use
    http://doc.qt.io/qt-5/qmake-variable-reference.html#includepath

    instead of linking to the file with full path



  • 4: #include <QMainWindow>
    I have no patch, I have a dynamic library.




  • Qt Champions 2016

    @Mikee
    not a patch, a path
    you include with
    #include "C:\Qt\project\MyCandleSrick\mainwindow.h"

    then in THAT mainwindow.h, if it tries to include something else
    it will look in the folder with the .pro file for the current project and
    will know nothing about MyCandleSrick folder.

    So im saying:
    it will not work good for you to include using full paths, it will not be able to find other files.
    and hence you should tell it with
    http://doc.qt.io/qt-5/qmake-variable-reference.html#includepath
    where ALSO to look for other files.
    Else it will miss what ever mainwindow.h also includes.



  • It is my *.pro file. What to do next?

    QT       -= gui
    
    TARGET = StrategyCod
    TEMPLATE = lib
    
    DEFINES += STRATEGYCOD_LIBRARY
    DEFINES += QT_DEPRECATED_WARNINGS
    
    SOURCES += \
            strategycod.cpp
    
    HEADERS += \
            strategycod.h \
            strategycod_global.h 
    
    unix {
        target.path = /usr/lib
        INSTALLS += target
    }
    
    INCLUDEPATH = c : / mainwindow.h/include
    

  • Qt Champions 2016

    @Mikee said in As dynamic libraries to use class variables?:

    INCLUDEPATH = c : / mainwindow.h/include

    That is complete wrong syntax ?

    INCLUDEPATH = "C:/Qt/project/MyCandleSrick"

    if that is the folder where it should look for the other files.



  • I replaced. What to do next?

    QT       -= gui
    
    TARGET = StrategyCod
    TEMPLATE = lib
    
    DEFINES += STRATEGYCOD_LIBRARY
    DEFINES += QT_DEPRECATED_WARNINGS
    SOURCES += \
            strategycod.cpp
    
    HEADERS += \
            strategycod.h \
            strategycod_global.h 
    
    unix {
        target.path = /usr/lib
        INSTALLS += target
    }
    
    #INCLUDEPATH = C: / Qt / project / MyCandleSrick/include
    INCLUDEPATH = "C: / Qt / project / MyCandleSrick"
    

  • Qt Champions 2016

    @Mikee said in As dynamic libraries to use class variables?:

    INCLUDEPATH = "C: / Qt / project / MyCandleSrick"

    Why the spaces ?
    Seems not correct.

    -What to do next?
    Depends on what you are trying ?
    If you can now build your library and get a DLL
    then you should load that library in your main app and
    try to call function StrategyCod2 with your data.

    https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application
    See section "Loading the library using QLibrary"

    Since you are not exporting void StrategyCod2()
    you need to resolve it to call it.
    http://doc.qt.io/qt-5/qlibrary.html#resolve



  • This is my library:
    StrategyCod.pro:

    QT       -= gui
    
    TARGET = StrategyCod
    TEMPLATE = lib
    
    DEFINES += STRATEGYCOD_LIBRARY
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which has been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    SOURCES += \
            strategycod.cpp
    
    HEADERS += \
            strategycod.h \
            strategycod_global.h 
    
    unix {
        target.path = /usr/lib
        INSTALLS += target
    }
    
    #INCLUDEPATH = C: / Qt / project / MyCandleSrick/include
    INCLUDEPATH = "C:/Qt/project/MyCandleSrick"
    

    strategycod.h:

    #ifndef STRATEGYCOD_H
    #define STRATEGYCOD_H
    
    #include "strategycod_global.h"
    
    
    extern "C" {STRATEGYCODSHARED_EXPORT void StrategyCod();}
    
    class STRATEGYCODSHARED_EXPORT StrategyCod
    {
    
    //public:
       // StrategyCod1();
    };
    
    #endif // STRATEGYCOD_H
    
    

    strategycod_global.h:

    #ifndef STRATEGYCOD_GLOBAL_H
    #define STRATEGYCOD_GLOBAL_H
    
    #include <QtCore/qglobal.h>
    
    #if defined(STRATEGYCOD_LIBRARY)
    #  define STRATEGYCODSHARED_EXPORT Q_DECL_EXPORT
    #else
    #  define STRATEGYCODSHARED_EXPORT Q_DECL_IMPORT
    #endif
    
    #endif // STRATEGYCOD_GLOBAL_H
    

    strategycod.cpp:

    #include "strategycod.h"
    #include <QDebug>
    //#include "C:\\Qt\project\\MyCandleSrick\\mainwindow.h"
    //#include <mainwindow>
    //StrategyCod::StrategyCod1(){qDebug()<<"Library work1";}
    
    
    
    void StrategyCod()
    {
        //MainWindow w;
        qDebug()<<"Library work2";//<<w.NBar;
    }
    

    This is my app
    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    #include <cstdlib>
    #include <QMessageBox>
    #include <QtConcurrent/QtConcurrent>
    #include <QMutex>
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;    
        QLibrary MyLib("C:\\Qt\\project\\build-StrategyCod-Desktop_Qt_5_9_2_MinGW_32bit-Debug\\debug\\StrategyCod"); 
        MyLib.load();
        typedef void (*MyPrototype)();
        MyPrototype StrategyCod = (MyPrototype) MyLib.resolve("StrategyCod");
        StrategyCod();  
        MyLib.unload();
        w.show();
        return a.exec();
    }
    

    In the MainWindow class is written needed variables.
    But I can not create an object of MainWindow class in the library and can't use its variables.


  • Qt Champions 2016

    Hi
    Ok, and you can call the void StrategyCod() function ? ( that works ?)
    If yes, you can now
    make it into

    void StrategyCod(MainWinow *main) ( it should know the type since u include its .h file)
    extern "C" {STRATEGYCODSHARED_EXPORT void StrategyCod(MainWinow *main);}

    and from main call it with
    typedef void (*MyPrototype)((MainWinow *);
    MyPrototype StrategyCod = (MyPrototype) MyLib.resolve("StrategyCod");
    StrategyCod(&w); // give it the real MainWindow

    There is no reason to try to create a new MainWindow inside the StrategyCod() function as
    that would be ANOTHER mainwindow than the running one and not have the right data.

    You should give it as parameter.

    Using mainwindow seems silly, a Data class would make more sense but can work.
    But you should NOT call any functions inside mainwindow from library as there is no event loop running and
    it will not work. But you should be able to use public member variables.



  • I can call the void StrategyCod() .
    I did:
    strategycod.h:

    #ifndef STRATEGYCOD_H
    #define STRATEGYCOD_H
    
    #include "strategycod_global.h"
    
    
    extern "C" {STRATEGYCODSHARED_EXPORT void StrategyCod(MainWinow * main);}
    
    class STRATEGYCODSHARED_EXPORT StrategyCod
    {
    
    //public:
       // StrategyCod1();
    };
    
    #endif // STRATEGYCOD_H
    

    strategycod.cpp:

    #include "strategycod.h"
    #include <QDebug>
    //#include "C:\\Qt\project\\MyCandleSrick\\mainwindow.h"
    //#include <mainwindow>
    //StrategyCod::StrategyCod1(){qDebug()<<"Library work1";}
    
    
    
    void StrategyCod(MainWinow * main)
    {
        //MainWindow w;
        qDebug()<<"Library work2";//<<w.NBar;
    }
    

    6 errors:
    C:\Qt\project\StrategyCod\strategycod.h:7: error: variable or field 'StrategyCod' declared void
    extern "C" {STRATEGYCODSHARED_EXPORT void StrategyCod(MainWinow * main);}
    ^
    C:\Qt\project\StrategyCod\strategycod.h:7: error: 'MainWinow' was not declared in this scope
    C:\Qt\project\StrategyCod\strategycod.h:7: error: 'main' was not declared in this scope
    extern "C" {STRATEGYCODSHARED_EXPORT void StrategyCod(MainWinow * main);}
    ^
    C:\Qt\project\StrategyCod\strategycod.cpp:9: оerror: variable or field 'StrategyCod' declared void
    void StrategyCod(MainWinow * main)
    ^
    C:\Qt\project\StrategyCod\strategycod.cpp:9: error: 'MainWinow' was not declared in this scope
    C:\Qt\project\StrategyCod\strategycod.cpp:9: error: 'main' was not declared in this scope
    void StrategyCod(MainWinow * main)
    ^


  • Qt Champions 2016

    Hi
    You must include mainwindw.h so it knows type

    trategycod.cpp:
    #include "mainwindow.h" // should know where to find it due to the INCLUDEPATH in .pro file



  • When i do this same error appers:
    C:\Qt\project\MyCandleSrick\mainwindow.h:4: error: QMainWindow: No such file or directory

    In the file C:/Qt/project/MyCandleSrick/mainwindow.h:
    4:#include <QMainWindow>


  • Qt Champions 2016

    @Mikee
    Well you library is with

    QT -= gui

    so it dont know QMainwindow type ( or any Qt widget type)



  • I fixed strategycod.pro:

    QT       += core gui
    
    TARGET = StrategyCod
    TEMPLATE = lib
    
    DEFINES += STRATEGYCOD_LIBRARY
    DEFINES += QT_DEPRECATED_WARNINGS
    SOURCES += \
            strategycod.cpp
    
    HEADERS += \
            strategycod.h \
            strategycod_global.h 
    
    unix {
        target.path = /usr/lib
        INSTALLS += target
    }
    INCLUDEPATH = "C:/Qt/project/MyCandleSrick"
    

    But the error is the same.



  • I done this in strategycod.pro

    INCLUDEPATH = "C:/Qt/project/MyCandleSrick"  "C:/Qt/Qt5.9.2/5.9.2/Src/qtbase/include/QtWidgets"
    

    Now it included <QMainWindow>. But it isnt working now

    extern "C" {STRATEGYCODSHARED_EXPORT void StrategyCod(MainWinow * main);}
    

    and

    void StrategyCod(MainWinow * main)
    

    errors:
    C:\Qt\project\StrategyCod\strategycod.h:7: error: variable or field 'StrategyCod' declared void
    extern "C" {STRATEGYCODSHARED_EXPORT void StrategyCod(MainWinow * main);}
    ^
    C:\Qt\project\StrategyCod\strategycod.h:7: error: 'MainWinow' was not declared in this scope
    C:\Qt\project\StrategyCod\strategycod.h:7: error: 'main' was not declared in this scope
    extern "C" {STRATEGYCODSHARED_EXPORT void StrategyCod(MainWinow * main);}
    ^
    C:\Qt\project\StrategyCod\strategycod.cpp:9: оerror: variable or field 'StrategyCod' declared void
    void StrategyCod(MainWinow * main)
    ^
    C:\Qt\project\StrategyCod\strategycod.cpp:9: error: 'MainWinow' was not declared in this scope
    C:\Qt\project\StrategyCod\strategycod.cpp:9: error: 'main' was not declared in this scope
    void StrategyCod(MainWinow * main)


  • Lifetime Qt Champion

    Because when you do INCLUDEPATH = you replace the content of that variable with what follows. Use INCLUDEPATH += to append your folders to it.



  • Now all includes are working.
    When I use function

    void StrategyCod(MainWindow * main)
    {
        //MainWindow w;
        main->NBar;
        qDebug()<<"Library work2"<<main->NBar;//<<w.NBar;
    }
    

    qDebug message is not a valid value NBar



  • I think that need to do reference class variable. But this code isn't working

    void StrategyCod(/*MainWindow * main*/)
    {
        long long &NBar1 =MainWindow.NBar;
        qDebug()<<"Library work2";//<<w.NBar;
    }
    
    

    How can i do reference?


  • Qt Champions 2016

    @Mikee

    via the parameter ( main or what u called it)

    void StrategyCod(MainWindow * main) {
        qDebug()<<"Library work2"<<main->NBar;
    }
    

    if NBAr is wrong, then something else is wrong. not the function
    it might be you call StrategyCod BEFORE setting it in mainwindow or
    something like that.



  • I checked:
    library:
    void StrategyCod(double Parametr)

    {
        MainWindow *w;
        qDebug()<<"Library work2"<<Parametr<<w->NBar;
    }
    

    main.cpp:

    QLibrary MyLib("C:\\Qt\\project\\build-StrategyCod-Desktop_Qt_5_9_2_MinGW_32bit-Debug\\debug\\StrategyCod");  
        MyLib.load();
        typedef void (*MyPrototype)();
        MyPrototype StrategyCod = (MyPrototype) MyLib.resolve("StrategyCod");
        qDebug()<<w.NBar;  //NBar=0 is hear 
        StrategyCod();  //NBar=5943858560 is hear 
        MyLib.unload();
    

    Maybe here typedef void (*MyPrototype)(); need append void (*MyPrototype)(class); ?


  • Qt Champions 2016

    @Mikee
    Yes it must all match.

    typedef void (*MyPrototype)();

    means pointer to function takes no parameters
    which is untrue.



  • But what to do with NBar?

    void StrategyCod()
    {
        MainWindow *w;
        qDebug()<<"Library work2"<<w->NBar;
      
    }
    

  • Moderators

    @Mikee

    typedef void (*MyPrototype)(MainWindow *w);
    


  • I have done this and it's working

     QLibrary MyLib("C:\\Qt\\project\\build-StrategyCod-Desktop_Qt_5_9_2_MinGW_32bit-Debug\\debug\\StrategyCod");  
        MyLib.load();
        typedef void (*MyPrototype)(MainWindow *);
        MyPrototype StrategyCod = (MyPrototype) MyLib.resolve("StrategyCod");
        StrategyCod(&w);  
        qDebug()<<"q1"<< q1;
        MyLib.unload();
    

    Thank you


  • Qt Champions 2016

    Congrats :)



  • I have are new problem.

    qDebug()<<NBar;
    

    return NBar=1064,

    qDebug()<<"Library work2"<< Parametr<<w->NBar;
    

    return NBar=0
    In class MainWindow:

    void MainWindow::on_ButtonRuneOne_clicked()//запуск стратегии на одном ядре
    {
        bool ok;
        double d = QInputDialog::getDouble(this, tr("ParametrForStrategy"),
                                               tr("double:"), 37.56, -100000, 100000, 6, &ok);
        if (ok) {ParametrForStrategyCod=d; }
    
        QLibrary MyLib("C:\\Qt\\project\\build-StrategyCod-Desktop_Qt_5_9_2_MinGW_32bit-Debug\\debug\\StrategyCod");  
        MyLib.load();
        typedef void (*MyPrototype)(double,MainWindow *);
        MyPrototype StrategyCod = (MyPrototype) MyLib.resolve("StrategyCod");
        MainWindow w;
        qDebug()<<NBar;
        StrategyCod(ParametrForStrategyCod,&w);  /
        MyLib.unload();
    }
    

    In library:

    void StrategyCod(double Parametr, MainWindow *w)
    {
        qDebug()<<"Library work2"<< Parametr<<w->NBar;
    }
    

    But in main.cpp it works good. How can I fix problem with link of object class?


  • Lifetime Qt Champion

    You're passing w to your method which is not the current MainWindow object you are calling StrategyCod from.

    Pass this to the method.

    On a side note, you are doing some pretty convoluted stuff here for what seems to be a pretty simple task. I'd encourage you to re-think a bit the design of your application.



  • Thank you. I wrote it like this

    StrategyCod(ParametrForStrategyCod,this); 
    

    and it works



  • How can I create lamda function in the slot of the class?

    
           QVector <double> Perebor1;
           for (double i=d1;i<=d2;i=i+d3) 
           {
               Perebor1.append(i);
           }
           QLibrary MyLib("C:\\Qt\\project\\build-StrategyCod-Desktop_Qt_5_9_2_MinGW_32bit-Debug\\debug\\StrategyCod");  
           MyLib.load();
           typedef void (*MyPrototype)(double,MainWindow *);
           MyPrototype StrategyCod = (MyPrototype) MyLib.resolve("StrategyCod");
           //StrategyCod(ParametrForStrategyCod,this);  
           QFuture<void> Perebor2 = QtConcurrent::map(Perebor1,[&](const double& d){ StrategyCod(d,this);}); 
           MyLib.unload();
    

Log in to reply
 

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