如何使用 dlsym 加载 QString 函数

How to dlsym load QString Function

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

QString pushdata(QVariantMap params);

这个函数放入库调用 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");

构建程序时出现错误:

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

我搜索 google 如何使用动态加载库并得到这样的说明 here here 任何人都可以告诉我如何在共享库中加载我的方法 QString pushdata(QVariantMap params)。我正在使用 EclipseCentos 6.5, Qt4.8

您可以使用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();
}

您可以使用 Qt 插件机制,如

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

  • 传递共享库的完整文件路径(例如 dlopen("./foo.so", RTLD_NOW) 不仅 dlopen("foo.so" ...) ...)并始终测试 dlopen 是否成功
  • 注意 name mangling,因此在您的插件中将 dlsym 编辑的函数声明为 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