how to load a dynamic library on demand from a QT method



  • I have dynamic library created as follows

    cat myfile.cc

    struct Tcl_Interp;
    extern "C" int My_Init(Tcl_Interp *) { return 0; }

    1. complile the cc file
      g++ -fPIC -c myfile.cc

    2. Creating a shared library

    g++ -static-libstdc++ -static-libgcc -shared -o libmy.so myfile.o -L/tools/linux64/qt-4.6.0/lib -lQtCore -lQtGui

    1. load the library from a TCL proc
      then I give command

    tclsh
    and given command
    % load libmy.so

    is there any C++/Qt function equivalent to load that can load the shared library on demand from another C++ function.
    My requirement is to load the shared library inside a function and then use the QT library , Is there any way I load the QT Library after call of certain function


  • Moderators

    @Qt-Enthusiast
    use QLibrary to load libs in an platform-independant way


  • Qt Champions 2017

    to add to @raven-worx , you can see example here
    https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application
    in Using QLibrary to load the shared library
    Note the
    CreateWidgetFunction cwf = (CreateWidgetFunction)library.resolve
    to actually call a function.



  • if I multiple calls of QT functions then do I need to resolve each an every call for exxample I have 1 lac calls to Qt functions then do I need to resolve each an every function


  • Qt Champions 2017

    @Qt-Enthusiast
    Hi
    I think yes. for your setup.
    Normally one can use plugins and interfaces and it removes the resolve part
    but you are using plain shared lib, so not not sure what u need or dont need :)



  • Can u guide how

    Normally one can use plugins and interfaces and it removes the resolve part
    but you are using plain shared lib, so not not sure what u need or dont nee



  • What is use of QLibrary::ResolveAllSymbolsHint


  • Moderators

    @Qt-Enthusiast said in how to load a dynamic library on demand from a QT method:

    What is use of QLibrary::ResolveAllSymbolsHint

    this just resolves all symbols at load time, as said in the docs.
    But still you need a pointer to the function you want to call.



  • Hi, you can use a function pointer like this:

    auto f = (void (*))(Tcl_Interp *) QLibrary("/path/to/libmy.so").resolve("My_Init");
    
    f(&my_tcl_struct);     // calls your function
    


  • for each Call to Qt function I need to have a function pointer correct ?



  • Sure, but if you only call a function once, you don't need to save the pointer, just use it directly, say like this:

    ((void (*))(Tcl_Interp *) QLibrary("/path/to/libmy.so").resolve("My_Init"))(&my_tcl_struct);
    

    Hope I got all the parentheses right :-)



  • after that can I call QT code dirrectlt

    QTreewidget* tree = new QTreeWidget()..



  • I do not need to link the QT library in my QExecutable


  • Qt Champions 2017

    @hskoglund
    That's why I usually typedef the type locally, looks simpler (and since I despise auto I'm a happy man not using it):

    typedef void (*MyInitPtr)(Tcl_Interp *);
    MyInitPtr My_Init = reinterpret_cast<MyInitPtr>( QLibrary("/path/to/libmy.so").resolve("My_Init") );
    if (My_Init)
        My_Init(&my_tcl_struct);
    

    @Qt-Enthusiast

    after that can I call QT code dirrectlt

    No, and you won't be able to accomplish that with QLibrary, it's a bit more involved than resolving a simple C-linkage function.



  • Two questions

    1 ) Do not need to link the QT library in my final Executable

    1. also Can u write a sample application how will multiple calls to many Qt functions codes can be called after

    typedef void (*MyInitPtr)(Tcl_Interp *);
    MyInitPtr My_Init = reinterpret_cast<MyInitPtr>( QLibrary("/path/to/libmy.so").resolve("My_Init") );
    if (My_Init)
    My_Init(&my_tcl_struct);


  • Qt Champions 2017

    @Qt-Enthusiast

    Okay, @mrjj encouraged me to give you the full reasoning why those shenanigans are bad. Hence, I'm going to do so. Suppose you have a class MyClass with declaration in "myclass.h":

    class MyClass
    {
    public:
        MyClass();
        ~MyClass();
    
        void myMethod(int);
    }
    

    and you want to call myMethod(int) of a newly created object of that class. But also suppose that class is compiled into a dynamic library myclasslib.so for all intents and purposes of this discussion. Suppose that the fully decorated symbols' names for the methods of this class are as follows:

    • MyClass::MyClass$constrDecoration for MyClass::MyClass
    • MyClass::MyClass$destrDecoration for MyClass::~MyClass
    • MyClass::MyClass$methodDecoration for MyClass::myMethod(int)

    So this is how you can create an object, call it's constructor, call the method and finally call the destructor and free the allocated memory (code is not tested, but should be working in principle):

    #include "myclass.h"
    
    int main()
    {
        MyClass * obj = reinterpret_cast<MyClass *>(::malloc(sizeof(MyClass))); // Allocate the object
        // Define two types for a pointer to method with and without an argument
        typedef void (MyClass::*MyMethodNoArgPtr)();
        typedef void (MyClass::*MyMethodIntArgPtr)(int);
    
        // Get the library
        QLibrary myLib("myclasslib.so"); //< This is the binary, in which the code for `MyClass` is compiled
        // Resolve the constructor, destructor and myMethod (notice the fully decorated symbols' names)
        MyMethodNoArgPtr _construct = reinterpret_cast<MyMethodNoArgPtr>(myLib.resolve("MyClass::MyClass$constrDecoration"));
        MyMethodNoArgPtr _destruct = reinterpret_cast<MyMethodNoArgPtr>(myLib.resolve("MyClass::MyClass$destrDecoration"));
        MyMethodIntArgPtr myMethod  = reinterpret_cast<MyMethodIntArgPtr>(myLib.resolve("MyClass::MyClass$methodDecoration"));
    
        // Wow, now we can actually call what we need
        (obj->*_construct)(); //< Call the constructor
        (obj->*myMethod)(10); //< Call MyClass::myMethod(10)
        (obj->*_destruct)()   //< Call the destructor
    
        // We can free the memory now
        ::free(obj);
        return 0;
    }
    

    This all would be equivalent to:

    #include "myclass.h"
    
    int main()
    {
        MyClass * obj = new MyClass();
        obj->myMethod(10);
        delete obj;
    
        return 0;
    }
    

    if we were to leave the loader to do what it's supposed to do!

    Oh, and by the way, this gets even more complicated when the objects have virtual tables (which QObject derived classes do).

    Two questions

    1. Do not need to link the QT library in my final Executable

    If you use Qt, you do.

    1. also Can u write a sample application how will multiple calls to many Qt functions codes can be called after

    I don't understand the question. What multiple calls to which many Qt functions do you have in mind?



  • because it application as big appilcation of Qt code


  • Qt Champions 2017

    @Qt-Enthusiast
    I don't follow.



  • for example

    I have GUI application which has 1 lacs of QT code

    for example

       QTreeWidget *w  = new QTreeWidget;
      QLabel * w = new QLablep
    
        class myTreeView:public QTreView {
         Q_Object
       };
    

    My question is If my load the dynamic library like

    is there direct way algorithm is

    void loadSharedObject() {  
        //load the
        // Call the function names directly
        // no extra code for resolving the function /symbols names   
        // for example  
         fun1()
         fun2()
     }
    


  • My question is If my load the dynamic library like

    is there direct way algorithm is

    void loadSharedObject() {
    //load the
    // Call the function names directly
    // no extra code for resolving the function /symbols names
    // for example
    fun1()
    fun2()
    }

    because the dyanamic libary in my is QLibrary


  • Qt Champions 2017

    @Qt-Enthusiast said in how to load a dynamic library on demand from a QT method:

    // Call the function names directly
    // no extra code for resolving the function /symbols names
    // for example

    No there isn't a way to do that. This is what linkers and loaders were created for. You can't leave a bunch of unresolved symbols that are supposed to be explicitly loaded at runtime, it just doesn't work that way.


Log in to reply
 

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