- In the world of Windows development, Win32 is the name of the entire programming interface (the API) used to interact with the operating system. When they later moved to 64-bit, instead of renaming it to "Win64," they kept the name Win32 for the API itself to maintain developer familiarity. Technically, 64-bit Windows programs run on the Win32 API for 64-bit systems. So, when the OS says "not a valid Win32 application," it really means "not a valid Windows DLL/exe"
- msvcr120.dll is a Dynamic Link Library (DLL) file that is a core component of the Microsoft Visual C++ Redistributable (Runtime) for Visual Studio 2013. Since the problematic PC never had any Visual Studio installed on it, it was missing the runtime dependency of my DLL.
- Shared runtimes are used to reduce the size of the compiled binary, but they introduce a dependency on the target operating system to provide the runtime.
- You can check the dependencies of your DLL or EXE by using Visual Studio's dumpbin.exe. On cmd, dumpbin /dependents filename.dll shows you the DLLs filename.dll depends on.
- If you see MSVCR....dll, you need the C Runtime.
- If you see MSVCP....dll, you also need the C++ Standard Library.
- If you see KERNEL32.dll or USER32.dll, don't worry, those are part of Windows itself and are always present.
- Previously, I discussed how to embed the C runtime in Linux. You can also embed/bake the C/C++ Runtime into your binary with Visual Studio via Project Properties > C/C++ > Code Generation > Runtime Library
- The default of /MD (Multi-threaded DLL) or /MDd (Multi-threaded Debug DLL) uses shared runtime
- Changing it to /MT (Multi-threaded), embeds the code into the DLL, leaving it with zero external dependencies. You can verify that your DLL has no dependencies (besides KERNEL32.dll) with dumpbin.exe.
- The disadvanages of /MT
- Larger file size
- If you have five different DLLs all compiled with /MT, each one has its own copy of the runtime in RAM. If they were compiled with /MD, they would all share a single instance of the shared DLL in memory.
- If a security flaw is found in the Microsoft C++ Runtime, Windows Update cannot fix your app. You would have to recompile your project with the latest patches and send the new DLL to your users.
- If you use /MT, make sure that any object created inside your DLL is also destroyed inside your DLL (e.g., using a DestroyObject() function you provide).
- For Debug, use /MDd because it is optimized for finding bugs, filling uninitialized memory with specific patterns (like 0xCCCCCCCC) etc.
- Windows folder names can be confusing:
- C:\Windows\System32: Contrary to the name, this folder is for 64-bit DLLs on a 64-bit version of Windows.
- C:\Windows\SysWOW64: This folder is for 32-bit DLLs. WOW64 stands for "Windows on Windows 64-bit".
C++ and MATLAB Simulink tips for HWIL simulation software engineers
Wednesday, February 4, 2026
Embedding Visual C++ Runtime into DLL
A user of one of my old desktop programs (written in Java8 and C++) reported that they were getting a "[FileName].dll is not a valid Win32 application." (the Turkish version: "... geçerli bir Win32 uygulaması değil"). Due to the "Win32" in the error message, my first thought was that they were using my 64-bit app on a 32-bit setup. However, that was not the case. They compared the PC that my app was working with the PC that was showing error and found out that they were able to make it work by copying mscvr120.dll file to Windows/System32 folder. After chatting with Gemini, here are my findings:
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment