如何dlsym加载QString函数

时间:2015-01-14 03:54:17

标签: c++ linux qt shared-libraries dynamic-loading

我正在尝试使用Qt为Linux系统编写C ++工具。我的工具使用共享库 我正在编写一个lib来将数据推送到数据库。头文件中的方法

QString pushdata(QVariantMap params);

这个fucion放入lib调用libpushdata.so。我想加载动态lib.so我使用 dlfcn.h 和类似的方法:

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

构建程序时出错:

  

从'void *'无效转换为'QString()(QVariantMap

我搜索谷歌如何使用动态加载库并获取类似here的指令  和here任何人都可以告诉我如何在共享库中加载我的方法QString pushdata(QVariantMap params)。我使用 Eclipse Centos 6.5 Qt4.8

2 个答案:

答案 0 :(得分:2)

您可以使用QLibrary动态调用函数。以下示例在运行时从共享库中调用函数:

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

答案 1 :(得分:1)

您可以使用Qt插件机制,answered by Nejat

如果您坚持只使用dlopen(3)dlsym,请注意:

  • 传递共享库的完整文件路径(例如dlopen("./foo.so", RTLD_NOW) dlopen("foo.so" ... ) ...)并始终测试dlopen的成功
  • 谨防name mangling,请在插件中将dlsym - ed函数声明为extern "C"
  • 明确地转换结果指针:

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

至少阅读C++ dlopen mini howto