user1095108
user1095108

Reputation: 14603

QPlugin path and initialization

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

Answers (1)

Nemanja Boric
Nemanja Boric

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

Related Questions