folibis folibis - 2 months ago 39
C++ Question

Load external dll in Qt in Windows

Assume, I have a folder with my program and also another folder with external library.

bin
myprog.exe
etc
lib.dll
sublib.dll


In my case I want to load the
lib.dll
from my main program
myprog.exe
. The problem is that
lib.dll
linked with
sublib.dll
.

So I try to do that in this way:

QCoreApplication a(argc, argv);
QLibrary lib;
QString path = "C:/etc/lib.dll";
a.addLibraryPath(path);

if(QLibrary::isLibrary(path)) {
lib.setFileName(path);
lib.load();
if(lib.isLoaded())
qDebug() << "Ok\n";
else
qDebug() << "Error " << lib.errorString() << "\n";
} else
qDebug() << "Not a library\n";
return a.exec();


After running the app I get the error:


cannot load library lib.dll the specified module could not be found


If I put both
lib.dll
and
sublib.dll
inside
bin
directory it works without error. But that is not I want to do.

I've tried

a.addLibraryPath("C:/etc");


but that doesn't work.
As I understand
QCoreApplication::addLibraryPath()
sets path for Qt program, not as system wide setting. So, in this case,
lib.dll
still can't find
sublib.dll
although it locates in same directory.

So my question - how can I load external shared library inside Qt program in case that this library has its own dependencies?

Answer

That is Windows issue. The DLL will be looked at the current process directory and then in the system PATH. The code that is contained in some C:\etc\lib.dll is behaving in its own process and unless very specific logic implemented will behave according to the system rule.

Please refer to MSDN article Dynamic-Link Library Search Order for details. If the source code for that lib.dll is available, it makes sense to examine LoadLibrary call. If there is no specific path provided then:

The first directory searched is the directory containing the image file used to create the calling process (for more information, see the CreateProcess function). Doing this allows private dynamic-link library (DLL) files associated with a process to be found without adding the process's installed directory to the PATH environment variable. If a relative path is specified, the entire relative path is appended to every token in the DLL search path list. To load a module from a relative path without searching any other path, use GetFullPathName to get a nonrelative path and call LoadLibrary with the nonrelative path. For more information on the DLL search order, see Dynamic-Link Library Search Order.