As dynamic libraries to use class variables?


  • Lifetime Qt Champion

    @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?


  • Lifetime Qt Champion

    @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); ?


  • Lifetime Qt Champion

    @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;
      
    }
    

  • Qt Champions 2018

    @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


  • Lifetime Qt Champion

    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();
    


  • And if I do, the function does not work.

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

    error:
    Invalid parameter passed to C runtime function.
    Invalid parameter passed to C runtime function.


  • Lifetime Qt Champion

    Well if Perebor2 still runs when you do MyLib.unload()
    its not so nice for it...



  • How to wait for all Perebor2?
    How to change w->NBar throw StrategyCod? If I do it in one thred

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

    it compiles, but when it works errors appears:
    ASSERT failure in QVector<T>::operator[]: "index out of range", file ....\Qt5.9.2\5.9.2\mingw53_32\include/QtCore/qvector.h, line 430
    Invalid parameter passed to C runtime function.
    Invalid parameter passed to C runtime function.


  • Lifetime Qt Champion

    @Mikee
    Dont wait for it.
    Just move the MyLib.unload(); to a better place.

    also if you have

    void mainwindow::somefunction {
    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();
    } // Perebor1 is deleted here.

    Perebor1 also dies as its a local
    so make them member variables of the class
    and structure code better.



  • `Perebor in class ,MainWindow. It doesn't work. Errors are the same.
    ``
    for (double i=d1;i<=d2;i=i+d3)
    {
    Perebor.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);});  
       QFuture<void> Perebor2 = QtConcurrent::map(Perebor,[&](const double& d){ StrategyCod(d,this);});
    

  • Lifetime Qt Champion

    What about Perebor2 ?
    Wont it suffer the same and run out of scope ?



  • No. It's okey with Perebor2. Function StrategyCod2 is in class MainWindow works correctly.

    for (double i=d1;i<=d2;i=i+d3) 
           {
               Perebor.append(i);
           }
    
           QFuture<void> Perebor2 = QtConcurrent::map(Perebor,[this](const double& d){ StrategyCod2(d);});
    

  • Lifetime Qt Champion

    @Mikee
    Ok for
    QLibrary MyLib;
    docs says
    QLibrary::~QLibrary()

    Destroys the QLibrary object.
    Unless unload() was called explicitly, the library stays in memory until the application terminates.

    so that seems ok.

    Im not sure what line gives the
    "Invalid parameter passed to C runtime function."

    You should use the debugger to find out.


  • Lifetime Qt Champion

    Out of curiosity, why are you dynamically loading that library since it's so tied to your application and that you are in control of both ?



  • Because I need to change the function code.
    There is problem in this string:

    QFuture<void> Perebor2 = QtConcurrent::map(Perebor,[&](const double& d){ StrategyCod(d,this);});
    

    because 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)(double,MainWindow *);
        MyPrototype StrategyCod = (MyPrototype) MyLib.resolve("StrategyCod");
        StrategyCod(ParametrForStrategyCod,this);  
        MyLib.unload();
    

    and it's working:

    for (double i=d1;i<=d2;i=i+d3) 
           {
               Perebor.append(i);
           }
    QFuture<void> Perebor2 = QtConcurrent::map(Perebor,[this](const double& d){ StrategyCod2(d);});
    

    Maybe it needs to insert something there:

    QFuture<void> Perebor2 = QtConcurrent::map(Perebor,[&](const double& d)(/*insert something there*/){ StrategyCod(d,this);});
    

Log in to reply
 

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