2

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

4

1 回答 1

2

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

一种)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,由 Qt 通过标准 Windows 系统调用在内部访问(例如,它们是使用LoadLibrary函数加载的,指向过程的指针是使用GetProcAddress,并且它们是通过FreeLibrary调用发布的),因此您可以尝试这种方法(我还没有测试过,这是一个丑陋的黑客,但它可能会起作用)。

// 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 系统上,插件是通过标准 dlopen() 系统调用加载的,因此您可以使用此处的解决方案。

于 2013-02-06T11:27:54.840 回答