Solved static library depending on a dynamic library
-
I have a static QT build with which I want to create a self contained executable. The program needs two libraries, lets call them LibA and LibB.
LibA is installed with a usb device driver and can be loaded dynamically.
LibB is a library that depends on LibA. I can link LibB statically on windows with a .lib file. There is also a .dll available.At the moment I added both libraries to my program via the project file like this:
LIBS += "$$_PRO_FILE_PWD_/liba/liba.lib" INCLUDEPATH += "$$_PRO_FILE_PWD_/liba/"
I would like to have one single .exe file to deploy and if LibA is not found be able to start the application anyway to display some error messages and supply the needed usb device driver for the user to download/install.
However at the moment if LibA is not found the app just crashes with no chance to do anythig about it.
I tried to load LibA dynamically with QLibrary which fixes the crashes only if LibB is not used.
Then I thought I can load LibB using QLibrary too (but only if LibA was successfully loaded). The Problem is that I don't know how to load the static linked LibB. Even if the library is added to the .pro file QLibrary can't find it. I also tried to put the .dll in a resource file but that didn't worked either. Is there a way to dynamically load a library without deploying it as a separate file?
-
@jsulm said in static library depending on a dynamic library:
You can't load a library directly from a resource. You will need to store it somewhere as file and then load it from there. But then I don't see the point to not simply deploy the lib as a normal shared library (you can't dynamically load a static lib).
The LibB is not created by myself and there is not installer available (that I can tell the user to install XYZ and then restart the application) and it can not be deployed to standard locations. The only chance I have is to use it static or bundle the dll.
The good thing is with QStandardPaths it is very straight forward to copy the dll directly from a resource file to a temporary folder and use it from there. I will do it this way now:
QString tempFolder = QStandardPaths::writableLocation(QStandardPaths::TempLocation); QString targetpath = QString(tempFolder) += QString("/LibB.dll"); QFile::copy(":/dlls_to_deploy/LibB.dll", targetpath); QLibrary library(targetpath); if (library.load()) { // do stuff with the lib }
-
@Scarab said in static library depending on a dynamic library:
I also tried to put the .dll in a resource file but that didn't worked either
You can't load a library directly from a resource. You will need to store it somewhere as file and then load it from there. But then I don't see the point to not simply deploy the lib as a normal shared library (you can't dynamically load a static lib).
-
@Scarab said in static library depending on a dynamic library:
I would like to have one single .exe file to deploy and if LibA is not found be able to start the application anyway to display some error messages and supply the needed usb device driver for the user to download/install.
@jsulm isn't exactly right, but close enough. What you're saying is you want to implement your own loader, and not just that, but one that's supposed to work on the different versions of windows you're going to deploy. This, albeit not impossible, is a task that's of dubious utility. I'd kindly suggest you give it up and stick to what's provided by the OS. I, personally, don't consider reinventing a functionality the OS already provides a productive time, with a very few minor exceptions for very niche uses.
-
@jsulm said in static library depending on a dynamic library:
You can't load a library directly from a resource. You will need to store it somewhere as file and then load it from there. But then I don't see the point to not simply deploy the lib as a normal shared library (you can't dynamically load a static lib).
The LibB is not created by myself and there is not installer available (that I can tell the user to install XYZ and then restart the application) and it can not be deployed to standard locations. The only chance I have is to use it static or bundle the dll.
The good thing is with QStandardPaths it is very straight forward to copy the dll directly from a resource file to a temporary folder and use it from there. I will do it this way now:
QString tempFolder = QStandardPaths::writableLocation(QStandardPaths::TempLocation); QString targetpath = QString(tempFolder) += QString("/LibB.dll"); QFile::copy(":/dlls_to_deploy/LibB.dll", targetpath); QLibrary library(targetpath); if (library.load()) { // do stuff with the lib }