I have a question about side-by-side assemblies.
Here's the situation:
I have an executable, app.exe, which loads plugins by searching a plugins directory. app.exe depends on a certain A.dll.
I'm developing a plugin which depends on an older, customized version of A.dll that has the same name. Updating this older, customized version to the newer version is impossible, so I thought I might be able to load the two A.dll files simultaneously.
Here's the directory structure:
\bin
app.exe
A.dll (newer version)
\plugins
myplugin.dll
Both versions of A.dll themselves depend on a huge number of other DLLs, which could have similar version problems. (I should also mention I'm working with a 64-bit application, if that makes a difference.)
How do I set this up in Visual Studio such that I can load both A.dll libraries at the same time, so that myplugin.dll uses the older version, whereas app.exe uses the newer version?
Since these are plugins, you load them by calling LoadLibrary, or similar. In which case you can simply pass the full path to the DLL in order to load it.
Related
Is there a way to deploy a Qt desktop application that is compiled using MSVC in such a way that it will be "portable" (just run exe from a folder, not install anything, not even install VC_redist)?
Of course, it is possible to use it if Microsoft Visual C++ Redistributable is installed on target computer, but is it possible to make it run without installing it (eg. by putting some dll from vcredist to application's folder)?
Just as you commented, you can use windeployqt to add Qt-related DLLs and resources. As for other required DLLs, you could use Dependencies to find them and MANUALLY copy them into your application folder, including MSVC DLLs.
PS: I know manually copy those DLLs is low efficient and fallible. This is why I ask Is there any way to search and copy all the DLL dependencies?, but I haven't found a tool smart enough to do this chore automatically. You might try those tools mentioned in the comments, like NDepend, though.
If you build/link your application statically, you will only have 1 .exe without DLL. The second way is to build your app with shared libraries and at runtime your app will search those DLL in PATH and in the current directory so you just need to put all your needed DLL in this folder. How do you manage your Qt library ?
I am working on porting an app of mine that I made in OS X to Windows 10. I'm using visual studio 2015 Community Edition.
To get the project running, I need to link against GLFW and, in Windows as I understand, GLEW, since I am targeting GL 4.5.
So I have the glfw and glew libs. I also use Cygwin so I have the libs installed in usr/local/(bin | lib | include) to mimic the folder structure I'd use in OS X for these libs.
The issue I'm having is with the opengl lib itself.
Until yesterday, I had managed to get my project compiling and initializing the glfw window with the following visual studio settings:
Project->Properties-> :
C++->General:
Additional Include Directories:
C:\cygwin64\usr\local\include
Linker->General:
Additional Library Directories:
C:\cygwin64\usr\local\lib
C:\cygwin64\usr\local\bin
Linker->Input:
opengl32.dll
glew32s.lib
glfw3.lib
The first thing to notice is that I was linking against opengl32.dll, not .lib. I saw a bunch of questions / posts online that state that when you install Windows SDK you have a opengl32.lib in Program Files/Microsoft SDKs/Windows (x86 or otherwise). This is not the case for me. I have even reinstalled the Windows 10 SDK and it does not install any opengl lib, static nor dynamic, anywhere.
So I'm pretty sure that my opengl dll was coming from Windows/System32 because that is the only place in the whole machine where there is any sort of opengl lib.
Which makes me think I might have also had C:\Windows\System32 in the linker's additional library directories section. I say makes me think, because I had set this up with a lot of struggle about a week ago. Since then I was able to develop just fine.
Last night all I did was commit my work to a git branch, switch to another branch and merge to that branch. After the merge, all Visual Studio linker/C++ settings were wiped. So I had to recreate them, as I showed above.
Now what happens is that if I include C:\Windows\System32 and the opengl32.dll VS spits out:
LNK1107 invalid or corrupt file: cannot read at 0x2E0 OpenVRTest C:\Windows\System32\opengl32.dll
And if I don't include it obviously half the stuff in glfw is unresolved.
Any hints as to how to get this working again?
It makes no sense to me... It was working just fine and it has to have been working fine with this opengl32.dll
Also as a side note, I'm not sure why people insist that installing the Windows SDK installs a static version of the gl lib; at least it does not for me.
Linker->Input:
opengl32.dll
glew32s.lib
glfw3.lib
That opengl32.dll is wrong. In Windows development the linker always takes .lib files. In case of static libraries the .lib contains the actual library binary. In case of DLLs the corresponding .lib informs the linker about which DLL to use and which symbols it offers.
The main reason for this particular choice of how things are to be done was, that in Windows development it shall be possible to link against a DLL without having the actual DLL around.
Also system libraries always are suffixed …32 even on 64 bit systems.
The issue was that among the VS configuration settings that got wiped, were a couple things related to x86 vs x64 platform settings. So the project was now trying to build for 64bit linking against the 32bit dll in System32.
So that's that.
A separate issue is why a lot of answers speak of an opengl32.lib (static) that theoretically comes with the Windows SDK but I have not seen it anywhere. I just link against the dynamic one.
I've written a game using OpenGL, GLFW, C/C++. I use third party libraries like SOIL and irrKlang. I use Microsoft Visual 2015. Both the debug and release version run ok from visual studio. In properties -> C++ -> Code Generation-> Runtime Library I selected /MDd. I did try other settings but the release version wouldn't work with any other. All of my .dll are saved in the release and debug folders.
However, when I go to my release folder and copy and paste the .exe found there, onto my desktop,it no longer runs. I keep getting a message that says the irrKlang.dll is missing. Could someone please explain how to get a standalone .exe of my game up and running?
Two things here. First, the .exe is the executable which contains the entry point of your application. So this is indeed the first piece you need. However, your application is allowed to depend on code that's not linked into it statically, but rather dynamically -- such dynamically linked code is only loaded at runtime. These runtime libraries of code are called DLLs ("dynamically linked libraries").
If your application depends on a DLL, it will look for that DLL while it's running. If it doesn't find it, you'll see that message box about a missing DLL. So, you need to copy not only the .exe file, but all the .dlls it depends on (and that they depend on) too. Note that your application links against many default system DLLs, e.g. kernel32, but these don't need to be copied next to the .exe because they're always present in the system search path.
Now, the second part. If you want to run your application on a PC that doesn't have Visual Studio installed, you need to make sure that computer has the C/C++ runtimes that the VS2015 toolchain automatically links against installed. These are not DLLs that you copy by hand; rather, there is a redistributable installer for them which installs them globally on the PC for all applications. You can ship this with your own installer.
For this to work, you want to be linking with just /MD in Release (the debug CRT is for debugging only, and is only installed when Visual Studio is installed -- it's not meant to run outside your PC).
This statement:
"Both the debug and release version run ok from visual studio. In properties -> C++ -> Code Generation-> Runtime Library I selected /MDd. I did try other settings but the release version wouldn't work with any other."
Leads me to believe that maybe you don't have a release version of one of your third party libraries.
/MDd causes your application to use the debug version of the MS runtime, which means that something in your project is being built with or as a debug version.
I use the 'depends.exe' application to see the dependencies of my executables and DLLs. It used to be provided directly by Microsoft, but now seems to be supported via a third party. Older SDKs will have it.
http://www.dependencywalker.com/
Static linking is not an option.
Let's say that I have an executable that relies on a DLL. One solution is to ship the DLL in the same folder as the executable. Now let's say that I need to inject a DLL into a process that relies on a DLL. Because the DLL is injected, where would I put the DLLs that it relies on? In the same folder? Or in the directory of the process that is injected to?
DLLs depending on one or more other DLLs is not something special. Even a trivial DLL will have dependencies on Windows shared components which are residing in other DLLs. A good example of these "shared components" would be Kernel32.dll and the CRT DLL such as MSVCR80.DLL etc.
You can find out exactly which other DLLs your DLL or EXE requires on by invoking the Dependency Walker. To do that, just run depends.exe from a Visual Studio Command Prompt and drag-and-drop the DLL of interest into the Window that appears. In case you don't have dependency walker available, you can download it from the above link.
I'm not sure of the DLL injection stuff, but it should generally be sufficient if you place all your (other DLL) dependencies in the same folder as your DLL, which would be the folder in which the EXE loading these DLLs resides.
Eg: If C:\test\foo.exe requires bar.dll (which in turn requires baz.dll, assuming baz.dll is not a standard windows shared component), then you would place both bar.dll and baz.dll in C:\test.
There is a lot more to how the OS determines which DLL to load, since multiple versions of the same DLL may exist at various locations and MSDN has a helpful article on the search order for dynamic linked libraries.
I'm wondering how to make a release build that includes all necessary dll files into the .exe so the program can be run on a non-development machine without it having to install the microsoft redistributable on the target machine.
Without doing this you get the error message that the application configuration is not correct and to reinstall.
Choose Project -> Properties
Select Configuration -> General
In the box for how you should link MFC, choose to statically link it.
Choose Linker -> Input. Under Additional Dependencies, add any libraries you need your app to statically link in.
You need to set the run-time library (Under C/C++ -> Code Generation) for ALL projects to static linkage, which correlates to the following default building configurations:
Multithreaded Debug/Release
Singlethreaded Debug/Release
As opposed to the "DLL" versions of those libraries.
Even if you do that, depending on the libraries you're using, you might have to install a Merge Module/framework/etc. It depends on whether static LIB versions of your dependencies are available.
Be aware that Microsoft do not recommend that you static link the runtime into your project, as this prevents it from being serviced by windows update to fix critical security bugs. There are also potential problems if you are passing memory between your main .exe and .dll files as if each of these static links the runtime you can end up with malloc/free mismatch problems.
You can include the DLLs with the executable, without compiling them into the .exe and without running the redist tool - this is what I do and it seems to work fine.
The only fly in the ointment is that you need to include the files twice if you're distributing for a wide range of Windows versions - newer OSs need the files in manifest-defined directories, and older ones want all the files in the program directory.
You'd be looking to static link (as opposed to dynamically link)
I'm not sure how many of the MS redistributables statically link in.
If you are looking to find out which dll's your target machine is missing then use depends.exe which used to come with MSDev, but can also be found here. Testing this on a few target machines should tell you which dll's you need to package with your application.
You should use a static link and add all libraries you need under additional dependencies.