Reputation: 14603
Does there exist a way for a Qt plugin to determine whether it is being initialized statically or dynamically? If it is being initialized dynamically, is there a way for a plugin to determine the path to its dynamic library (.dll or .so)?
Upvotes: 2
Views: 938
Reputation: 22187
In QPluginLoader you have two functions you may take a look:
a) QObjectList QPluginLoader::staticInstances ()
Returns a list of static plugin instances (root components) held by the plugin loader.
b) QString fileName () const
This property holds the file name of the plugin. To be loadable, the file's suffix must be a valid suffix for a loadable library in accordance with the platform, e.g. .so on Unix, .dylib on Mac OS X, and .dll on Windows. The suffix can be verified with QLibrary::isLibrary().
Unfortunately, if you don't have plugin loader for specific plugin there is not a lot you can do. Plugins don't require any special interface, and they can be derived directly from QObject
. Exporting plugin with Q_EXPORT_PLUGIN2
will only declare QObject
pointer to plugin instance with qt_plugin_instance
prefix.
Loading the plugin will not call any specific function, so I don't see a way to provide it to the plugin itself.
However, you can do something, if you are willing to lost portability: On Windows, plugins are just dlls, which are accessed internally by Qt via standard Windows system calls (for example, they are loaded using LoadLibrary
function, pointers to procedures are found using GetProcAddress
, and they are released with FreeLibrary
calls), so you could try this approach (I haven't tested it, it is an ugly hack, but it may work).
// 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);
It seems that any EXE or DLL compiled with the VS2002 (and higher) linkers provides a psuedo-variable called __ImageBase that represents the DOS header of the module (all 32 bit binaries have this). Simply cast this variable to a HINSTANCE, and you can pass it as the first parameter to GetModuleFileName().
On Unix systems, plugins are loaded via standard dlopen() system call, so you could use solution from here.
Upvotes: 2