How to organize Qt DLLs with Qt-based dependency - c++

I have a Qt application using Qt 4.8.5. This application is dependent on a DLL that was built using Qt 4.6.0. Let's call it "MyDLL.dll".
I cannot rebuild MyDLL.dll to update it to a more current version of Qt. Since both my application and MyDLL require the QtCore and other DLLs, and the versions are different, how do I organize my files such that they don't conflict?
MyDLL is required at startup, so I can't use any delay load methodologies.
edit: To be clear, this question came up because the MyDll.dll was built using a custom Qt 4.6.0 from modified source, and my application is using a custom build of 4.8.5. The modifications weren't necessarily the same in both versions, so I didn't want to assume that I could still use the 4.8.5 DLLs. Turned out that it worked out in this case, but the question stands.

You shouldn't be having any issues. Qt maintains binary compatibility over minor and patch releases (see http://qt-project.org/wiki/Qt-Version-Compatibility) and an application/DLL built with 4.6.x will run fine when bound to 4.8.x runtime.
Your MyDLL.dll built with 4.6.0 will run with 4.8.5 runtime DLLs.
Your application built with 4.8.5 will run with 4.8.5 runtime DLLs.
Your application will run fine with MyDLL.dll as long as you are using the same interface you've always been using.
If you are seeing issues it is because of something else, and you will need to clarify exactly what problem you are having.
If you are not seeing issues and are just asking preemptively, then 1) just proceed as normal with no special considerations, and 2) you should have tried it first!

Welcome to DLL Hell! :(
This is a huge problem under Microsoft windows, since the standard isn't to build version information into the DLL file name (like with Linux .so files).
You won't be able to accomplish what you are after if you link directly against "MyDLL.dll" since it will be looking for QT DLLs (like QtCore, QtGui, etc). The stock Qt DLLs contain no version decoration in the filename, so there will be a conflict as to which one to load. Also, you will likely not be able to link correctly in the first place (due to the conflicts. Qt doesn't play well with older versions).
The only possibility might be to create a separate executable that links against Qt 4.6.0 and MyDLL, and use some out-of-process communication between your main app and the server. COM might work in this case, but it largely depends on what your dll actually does.
The only other course of action would be to downgrade your main application and fix it at Qt 4.6.0.

Jason C's answer got it right. Also note the following:
MyDll.dll must be compiled with the same compiler version as the rest of your application.
The version of Qt used to build MyDll.dll should have had the same major configuration flags as the version of Qt that you're currently using. Things such as Qt namespaces, QThread support, etc. must all be the same.

Related

Do QT based GUI applications work in Windows PE?

I tried running a QT C++ GUI sample in WinPE. It should just open an empty window.
It complains about missing d3d11.dll and dxgi.dll.
QT tries to use OpenGL, if there is no suitable driver, it uses DirectX with ANGLE. I tried removing the DirectX dependency by calling Qapplication::setAttribute(Qt::AA_UseSoftwareOpenGL) before the Qapplication instantiaton. No change, still requires those two dlls.
I tried to copy those two files from my regular Windows, and now the error is: “The procedure entry point CheckIsMSIXPackage could not be located in the dynamic link library dxgi.dll”
I don't need any HW acceleration, how could I make it run?
QT version: 5.14.2 (dynamic linking)
WinPE version: Windows 10 2004
Compiler: Visual Studio 2019 and Mingw 8.1 (I have tried both, same results)
Too late ? Not the solution but only an idea.
Actually I use Winpe WinPe 2009. When i install VirtualBox 6.1.16 in this winpe, i add opengl32.dll and other files. VirtualBox uses QT5 files. And i get the same error. With Depends.exe, i see that opengl32.dll needs this ChechIsMSIXPackage and loock for it in kernelBase.dll. But because kernelBase.dll which comes with winpe2009 doesn't contain this API, i take this kernelBase.dll from a normal W10 (in the ISO/Install.wim). And, in my case, virtualBox works well, QT5 also, opengl32 also.
Qt 5.12 does not depend on dxgi.dll but Qt 5.15 definitely seems to.
One option is to roll back your project to Qt 5.12, I can personally confirm that Qt 5.12 projects work great under Windows PE.
(This is assuming you are using the prebuilt Qt binaries from Maintenance Tool - otherwise there may be a config option to recompile Qt to avoid this).
It's late but since I just ran into this problem myself...
Apparently this dependency is introduced by the Rendering Hardware Interface, and what worked for me for WinPE 1809 was to build Qt 5.15 (.7 and .8) from source - in Msys2, by the way - after removing/commenting out the line include(rhi/rhi.pri) in qtbase/src/gui/gui.pro, and the configure command line includes -no-directwrite -no-opengl -no-icu.

Dll loaded by application only in qt debugger but not independently

After cleaning and reinstalling windows 7, I've installed qt 5.11. However, my old plugin (dll) which I developed using qt 3 is no longer recognized by the application. But the application recognizes the dll in debugger mode.
I have tried copying dependent libraries which the debugger loads to the dll location but this has not worked. I have also removed references to qtcore etc but even this has not worked. I do not know what I am missing.The plugin ran fine in the old version of qt but not in the newer version of qt.
Thanks for any help that you can give.
Qt does not provides binary backward compatibility between major versions.
You must update (== compile and build your plugin dll with Qt5) to have it working.
see this page
https://wiki.qt.io/Qt-Version-Compatibility#Binary_Compatibility_Guidelines

Statically link with Microsoft CRT, and OpenMP

I’m developing some Windows software that's sometimes used in embedded-like scenarios. That’s not uncommon for my users to have a dedicated Win7 or Win8 PC they never update, not even connect to the Internet. Users plug those PC to a specific industrial hardware, and use that system for one job only.
My software includes components I've written in Visual C++. I include CRT in my MSI packages using appropriate installer merge modules.
Unfortunately, for a PC that never updated, that doesn’t work: today I got a bug report, the app crashes on startup saying “can’t start because api-ms-win-crt-stdio-l1-1-0.dll is missing from your computer”
This answer suggests static link to CRT.
Did that. But some parts of my C++ code rely on OpenMP for parallelism.
Dependency walker shows me the DLL I’m building depends on vcomp140.dll even when compiled with Multi-threaded (/MT) runtime library settings.
Also it shows vcomp140.dll only depends on kernel32.dll and user32.dll.
Can I just place that single DLL, vcomp140.dll, in the installation folder? Will it work on offline Windows 7 PC?
Based on the VS2015 Redistribution List I would say that copying that file would be indeed what you need to do and would work fine (if you used VS2015 to build your app). Take care to copy the proper dll based on arm/x86/x64.
Just to make it clear, it is not possible to statically link openmp with Visual Studio. Only two things you can do:
Remove openmp (and compile with /MT /MTd)
deploy vcomp140.dll (or VC redistributable) with your application

Can a single eclipse C++ project link different libraries differently for different platforms?

I have a C++ eclipse project that I would like to easily compile In Windows and OSX.
The project is currently using an automatically generated makefile.
The libraries that I need vary depending on the platform.
In osx I'm using the CoreMidi, CoreAudio, and CoreFoundation frameworks.
In Windows I'm using the winmm.lib and multithreaded libraries.
What's the simplest way to link different libraries/frameworks depending on the current platform?
I'm currently using the gcc toolchain on OSX. Should I start using the cross compile toolchain?
Should I have two projects. One for working in windows, and one for osx, checking them both in to version control?
Should I write a custom makefile instead of using the automatically generated option that has different g++ arguments depending on the platform?
I personally had the same goal for a project and came to the conclusion the Qt framework was the best thing for me. It handles multiple languages, unicode strings, XML, network communications, native looking user interfaces, console applications: it can do an AWFUL lot.
However, as Paul pointed out, you really have to plan it from the start.
Qt does a good job of abstracting the platform away (in a module called QtCore) allowing you to write vanilla C++ code, or you can chose to include some Qt C++ language extensions which a Qt helper application called the moc (meta object compiler) creates vanilla C++ from, which can then be compiled by most common C++ compilers.
It also has a nifty cross-platform makefile generator called qmake which works on project files to create normal make files for the platform its running on.
Off the top of my head at least Windows XP & 7, OSX 10.4, 10.5, 10.6 are supported currently. But note that OSX Lion is (as of writing) not officially supported but I suspect it will be in the next release.
Based on your description, I am not sure you can easily make it cross-platform. Even without using third-party library, you have to provide separate code for osx and windows. Most of time, they design the system as cross-platform first. It's really hard to make an existing project on single-platform to cross-one. If you have the cross-platform requirement, you'd better design in that way first and rewrite from scratch.
Even though Eclipse can run fine on both OS X and Windows, it is not designed to be used in this way.
The best way to do it is to use separate IDE projects for each platform. This this is the easiest way to have unique compilation settings for multiple platforms.
Yes, you can use two eclipse projects. Alternatively, it's not unusual to have a X-Code project for OSX, and a Visual Studio Project for MS Windows.

Want to run a program on some unknown system

I have been working on a VS 2005 project and have successfully generated an exe file which works fine on my system. However when I tried to run it on some other pc it didnt run. It throws up the error message "the system cannot run the specified program". Can someone tell me how to make my code immune to such message i.e. system independent?
platform used: Windows XP, VS 2005
the extension of all my code files is cpp but I know only c and thats what I wrote inside them.
I have seen before exe created on Windows Sp1 not working on SP2 and problems such as that.
This should help you perhaps.
I've seen this when you run on a different version of Windows that doesn't have some DLL you depend on. The easiest thing to do is statically link the C runtime (that's the usual culprit) and use depends.exe to see if there are any others.
You will almost certainly need to create an installer that installs your executable and any non-OS-included DLL's it relies upon. It is not always possible or desirable to statically link all dependencies. You can in many cases simply copy the DLL's to the same folder as the executable.
By default, even the C/C++ standard library is provided by a DLL. While the MSVCRT.DLL used by VC++ 6 is included with the OS since later editions Win95, the MSVCRT required by VS2005 is not included with XP installations (other versions I do not know). The run-time support is included VC redistributes package. You may need to arrange for your installer to include that installation, or you could be more selective is you know your dependencies.
Some Win32 API calls if you are using them are dependent on the OS version (check the documentation), but if you built and rin it on XP, it should normally work of any subsequent version of Windows. You need to define various API version macros if you want to extend support to earlier versions of Windows (which seems unlikley).
You might need to install the VS 2005 redistributables on the other machines, depending on how you have compiled your program.