2

I'm trying to write a C++ tool using Qt for linux system. my tool using shared lib I'm writing a lib to push data to database. method like that in header file

QString pushdata(QVariantMap params);

this fucion put in lib call libpushdata.so. I would like to load dynamic lib.so I'm using dlfcn.h and method like that:

void *handle;
QString (*pushdata)(QVariantMap*);
handle = dlopen("libpushdata.so", RTLD_LAZY);
if (!handle) {
    fputs(dlerror(), stderr);
    exit(1);
}
pushdata=dlsym(handle,"pushdata");

when build program I get error:

invalid conversion from ‘void*’ to ‘QString ()(QVariantMap)

I search google to how to use dynamic load library and get the instruction like that here and here anyone can show me how to load my method QString pushdata(QVariantMap params) in shared lib. I'm using Eclipse and Centos 6.5, Qt4.8

Cœur
  • 37,241
  • 25
  • 195
  • 267

2 Answers2

2

You can use QLibrary to call functions dynamically. The following example calls a function from a shared library at runtime:

#include <QLibrary>
#include <QDebug>

typedef QString (*call_func)(QVariantMap* arg1);

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QLibrary library( "dynamic_library" );
    library.load();
    if( !library.isLoaded() )
    {
        qDebug() << "Cannot load library.";
        return 0;
    }
    call_func func = (call_func)library.resolve( "pushdata" );
    if(func)
    {
        func(variantMap);
    }

    return a.exec();
}
Nejat
  • 31,784
  • 12
  • 106
  • 138
  • thanks @Nejat, im try your method and still get error `error while loading shared libraries: liblibtest.so: cannot open shared object file: No such file or directory` – Trương Hồng Quyền Jan 14 '15 at 05:20
  • Do you place the so file alongside the executable? – Nejat Jan 14 '15 at 05:25
  • Are you linking the library to your application? Or you want to load it dynamically? – Nejat Jan 14 '15 at 05:27
  • im also link my application to library, but it still error. when i cd to directory contain application and use `exprot LD_LIBRARY_PATH=/root/Desktop/loaddl/Debug` and `./application` application run normally, Debug folder contain lib.so @@ .So can you tell me how to run applcation withou using `exprot LD_LIBRARY_PATH` only use ./application to run – Trương Hồng Quyền Jan 14 '15 at 08:06
  • If you want to load the library dynamically at run time, why are you linking it to your application? There is no need to link if you want to load dynamically. – Nejat Jan 14 '15 at 08:17
  • 1
    If you want to link the library to your application, then there is no need to use `QLibrary`. You can simply include the header file and use the classes. In this case just put the so file alongside the executable and add some lines to your pro file to tell the dynamic linker to look in the same directory as the application, see : http://stackoverflow.com/questions/23896643/qt-program-does-not-detect-libraries/23902272#23902272 – Nejat Jan 14 '15 at 08:22
  • thanks @Nejat im using your example and remove link lib to application and it run ok – Trương Hồng Quyền Jan 14 '15 at 08:44
1

You can use Qt plugin machinery, as answered by Nejat.

If you insist on using just dlopen(3) and dlsym take care about:

  • passing a full filepath of the shared library (e.g. dlopen("./foo.so", RTLD_NOW) not only dlopen("foo.so" ...) ...) and always test the success of dlopen
  • beware of name mangling so declare the dlsym-ed function as extern "C" in your plugin
  • casting explicitly the resulting pointer:

    typedef QString pushdata_sig_t(QVariantMap*);
    pushdata_sig_t* pushdata 
      = reinterpret_cast<pushdata_sig_t*>(dlsym(handle,"pushdata"));
    if (!pushdata) 
      { std::cerr << "dlsym failed:" << dlerror ()
                  << std::endl; 
        exit(EXIT_FAILURE); }
    

Read at least the C++ dlopen mini howto

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547