【问题标题】:QPlugin path and initializationQPlugin 路径和初始化
【发布时间】:2013-02-06 10:48:17
【问题描述】:

Qt 插件是否存在一种方法来确定它是静态初始化还是动态初始化?如果是动态初始化的,插件是否有办法确定其动态库(.dll 或 .so)的路径?

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    QPluginLoader 有两个函数,你可以看看:

    a)QObjectList QPluginLoader::staticInstances ()

    返回插件加载器持有的静态插件实例(根组件)的列表。

    b)QString fileName () const

    此属性保存插件的文件名。 要可加载,文件的后缀必须是符合平台的可加载库的有效后缀,例如Unix 上的 .so、Mac OS X 上的 .dylib 和 Windows 上的 .dll。后缀可以通过 QLibrary::isLibrary() 进行验证。

    不幸的是,如果您没有特定插件的插件加载器,那么您无能为力。插件不需要任何特殊接口,可以直接从QObject派生。使用Q_EXPORT_PLUGIN2 导出插件只会声明QObject 指向带有qt_plugin_instance 前缀的插件实例的指针。

    加载插件不会调用任何特定函数,所以我看不到将其提供给插件本身的方法。

    但是,如果您愿意失去可移植性,您可以做一些事情:在 Windows 上,插件只是 dll,可通过 internally by Qt via standard Windows system calls 访问(例如,它们是使用 LoadLibrary 函数加载的,找到指向过程的指针使用GetProcAddress,它们是通过FreeLibrary调用发布的),所以你可以试试this approach(我还没有测试过,这是一个丑陋的hack,但它可能会起作用)。

    // near the top of your CPP file
    EXTERN_C IMAGE_DOS_HEADER __ImageBase;
    
    // and then, anywhere you need it:
    LPTSTR  strDLLPath1 = new TCHAR[_MAX_PATH];
    ::GetModuleFileName((HINSTANCE)&__ImageBase, strDLLPath1, _MAX_PATH);
    

    似乎任何使用 VS2002(及更高版本)链接器编译的 EXE 或 DLL 都提供了一个名为 __ImageBase 的伪变量,它表示模块的 DOS 头(所有 32 位二进制文​​件都有这个)。只需将此变量转换为 HINSTANCE,即可将其作为第一个参数传递给 GetModuleFileName()。

    在 Unix 系统上,plugins are loaded via standard dlopen() system call,因此您可以使用来自 here 的解决方案。

    【讨论】:

    • 这只是部分答案。我同意staticInstances() 可能有用,但不是fileName(),因为动态插件不会自行加载,因此无法访问加载它的QPluginLoader 实例。
    • @user1095108 我已经编辑了我的帖子以包含更多信息。
    • @user1095108 在 Linux/OS X 上还有更简单的方法:stackoverflow.com/questions/1681060/…
    猜你喜欢
    • 2016-06-15
    • 1970-01-01
    • 2020-05-14
    • 2015-12-16
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多