Visual Studio 2017 looking for DLL rather than a LIB - c++

A C/C++-Win32-project used to compile, link and run just fine using Visual Studio 2010. This project uses a 3rd party library XYZ.LIB that comes as a (statically linked) object library (not an import library).
I transferred this project to Visual Studio 2017 and while it still compiles, it won't run anymore. Upon starting the programm, a message pops up telling that XYZ.DLL (!) is missing. I already added XYZ.LIB under Project -> Properties -> Configuration Properties -> Linker -> Additional Dependencies. I actually don't have the XYZ.DLL and VS2010 never complained about needing a DLL rather than the provided LIB.
How can I get VS2017 to use the regular LIB rather than looking for a DLL with the same name ?

Related

In Visual Studio 2019, linking plain C++ project to Dot Net 5 project builds an invalid executable

Summary: I am using Visual Studio 2019, and trying to create an example that links a plain-old-C++ project to a C++/CLR project that targets .NET 5.0. The solution compiles and builds, but attempting to run it produces an error message saying "not a valid Win32 application."
Question: How can I produce an executable that will actually run?
Steps to reproduce:
Using Visual Studio 2019, create a new solution. Set the configuration to Debug and x86.
Create a new project that is a C++ desktop application, using the C++ Windows Desktop Wizard project template with default options. Name it Interop5Test, and verify that it builds and runs.
Create a new project that is a C++/CLR project targeting .NET 5.0, using the C++ CLR Class Library (.NET Core) template, and name it CppShim5.
Modify the properties and source files of CppShim5 to remove the use of precompiled headers. (I did so to match the requirements of my intended use case.) Verify that the solution still builds and runs.
In the project properties for Interop5Test:
modify Linker | Input | AdditionalDependencies by adding ../CppShim5/$(Configuration)/CppShim5.obj
modify Linker | General | AdditionalLibraryDirectories by adding
C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x86\5.0.3\runtimes\win-x86\native
(or wherever ijwhost.lib can be found on your machine).
Build the solution, which should succeed.
Press Local Windows Debugger in Visual Studio to start the executable, and observe a popup window that says "Unable to start program ... not a valid Win32 application."
Browse to the Debug folder of the solution, and observe that Interop5.exe, CppShim5.dll, ijwhost.dll, and CppShim5.runtimeconfig.json are all present.
Use ildasm to examine Interop5.exe and CppShim5.dll, and observe that they are 32-bit portable executables with COFF Header | Machine value of 0x14c which means "Intel 386 or later processors and compatible processors."
Open ijwhost.dll with Visual Studio and observe a reasonable looking Version resource. Perform a binary comparison of ijwhost.dll with the one in the additional library directory of step 5, and observe that the files match perfectly.
Examine the contents of CppShim5.runtimeconfig.json and see something that looks reasonable.
I discovered that I can get a valid executable if I link to CppShim5.lib instead of CppShim5.obj.
Details for how to alter the example in the original question:
Add a class to CppShim5 and mark it as exported from the DLL (by using __declspec(dllexport), see also: https://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport?view=msvc-160). This causes Visual Studio to generate CppShim5.obj and to put it in the Solution's Debug folder.
Edit the properties of Interop5Test, changing Linker | Input | AdditionalDependencies from: ../CppShim5/$(Configuration)/CppShim5.obj to: ../$(Configuration)/CppShim5.lib
In Visual Studio, add to project Interop5Test a dependency on project CppShim5.
With these changes, build the solution. It should now execute.

Visual Studio Static Linking for Standalone Exe

I've read multiple posts with regards to this topic, but none of them have enabled me to build a statically linked exe.
In my release configuration (x64) I have the following:
Configuration Properties -> General : Use of MFC - Use MFC in a Static Library
Configuration Properties -> C/C++ -> Code Generation : Runtime Library - Multi-threaded (/MT)
Configuration Properties -> Linker -> Command Line : Additional Options - I have all the required Windows libs "kernel32.lib", etc. (as use of MFC removed them from the "All Options" window above)
Configuration Properties -> Manifest Tool -> Input and Output : Embed Manifest - No
Note that in Configuration Properties -> Linker -> Input there are 5 lib files that I'm using in my project, eg glfw3.lib and I'm using Full optimisation (/Ox).
After building the project and running the exe myself I receive errors "The code execution cannot proceed because glfw3.dll was not found..." etc.
Using dependencywalker I can see that it needs the dlls associated with the libs, which it of course cannot find.
Am I misunderstanding how to do this or is there something else that might be wrong?
(I'm using Visual Studio 2017)
Yes, it appears you have a slight misunderstanding.
If something is offered as a DLL, then it is meant to be used as a DLL. There may be some way to incorporate a DLL into an executable, but it would be a hack. That's not how things are supposed to work.
The lib file that you are linking against exists simply in order to provide you with functions that you can link against, and these do nothing but delegate to the corresponding functions in the dynamically loaded DLL. Without it you would have to locate each entrypoint of the DLL yourself, which would be perfectly doable, but a bit cumbersome.
So: you must either find a version of glfw3 which is packaged as a statically linkable library (I have no idea whether one exists) or live with the fact that your .exe will need to be shipped together with glfw3.dll.

Using a static library when building a DLL in visual studio

I'm trying to build a DLL using Visual Studio 12 Community that depends on OpenCV.
I want to include OpenCV as .lib files so I don't have to distribute it seperately, but I need my file to be built as a DLL.
But I can't configure Visual Studio to import a lib into a DLL. If in
My Project -> Properties -> Configuration Properties -> General -> Configuration Type,
I select "static library (.lib)" and in:
My Project -> Properties -> Configuration Properties -> VC++ Directories -> Library Directories,
I select the path to the OpenCV .lib files, and in
My Project -> Properties -> Configuration Properties -> Linker -> Addition Dependencies
I add a reference to each .lib, it works.
But if I change the Configuration Type do "dynamic library (.dll)", Visual studio tells me:
opencv_highgui2410d.lib(window.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in VectorsImport.obj
It seems I can only make .lib files with .lib files. But that seems very unlikely. I've looked this up, but I only find guides on how to make .lib files or .dll files or one out of the other. This must be pretty simple, but I can't figure it out. I'm used to Linux, where a .o can pretty easily be included into a .so . This puzzles me.
The error indicates that you are trying to link a OpenCV module which has been compiled for using the static C/C++ runtime with debugging support with a module VectorsImport.obj (probably from your own project), which has been compiled for using the dynamic C/C++ runtime with debugging support. The four variants of the C runtime library are not compatible in the Microsoft SDK, so all object files (either from your project or from statically linked libs) have to match on that setting. On Visual Studio 2010, it could be found at C/C++-Compiler -> Codegeneration -> Runtime library.
Please note that (as the bold face should emphasize) it is not about OpenCV being a DLL or .lib, but in case OpenCV is linked as separate DLL, it is allowed to use a different kind of C runtime library, so the mismatch does not matter.

How to not link against msvcr100.dll?

I am compiling project in Visual Studio 10, compiled executable runs fine on win 7 but it doesnt works on win xp because of missing msvcrt100.dll.
I tried to use "/NOTDEFAULTLIB" but it also removes some other external libs that i use.
Is there way to not link against latest Microsoft runtime library ?
Thanks in advance.
To not link against the DLL you must link against the runtime statically.
To do this, go to C/C++ Properties -> Code Generation and under Runtime Library select Multi-threaded (/MT) or Multi-threaded Debug (/MTd) from the drop-down. Note, once you're using a static runtime library all of your other library code you link against must also be built with the same setting. And you will also likely have to add additional libraries to the Linker -> Input under Additional Dependencies.
It only works on Windows 7 machine by accident, somebody installed that DLL earlier.
Short from creating an installer (easy to do with a Setup project), a simple fix is copying msvcr100.dll along with your own binaries. If you only have an EXE then the simple solution is to link the static version of the CRT. Switch to the Release build, right-click the project, Properties, C/C++, Code Generation, Runtime Library setting. Change it to /MT from the default /MD.

A C++ Application Compiled With VS2008 Doesn't Run In Other Computer

I have created a wn32 project with Visual Studio 2008 and Visual C++ language, it uses the ws2_32.lib library and then I compiled in Release mode.
It runs very good in the same computer, but when I copy the exe file to other computer (that doesn't have installed Visual Studio), it doesn't run.
The message I see is:
This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.
But, if I compile my application using DEV C++, it generates a bigger executable (738KB) compared with the Visual Studio 2008 executable (9.5 KB). However, the DEV C++ executable runs in the other computer.
I have add the library ws2_32.lib to the linker properties of my project, in the Additional Dependencies field.
How can I fix it to work with Visual Studio 2008?
My code is the following: http://www.stan.com.mx/yupi/udpserver.cpp
The problem is almost certainly that the other computer does not have version 9 of the C++ CRT installed.
The default setting for compiling against the CRT in VS2008 is to dynamically link vs. statically linking. If you want to deploy your program with a real setup project you'll need to include the CRT redistributable.
However if you want to do an XCOPY deployment follow the steps on the following page.
http://msdn.microsoft.com/en-us/library/ms235291.aspx
Try installing the Visual C++ redistributables. If that doesn't work, use DependencyWalker to find out what DLLs are missing.
I agree with JaredPar. The application you build with VS2008 is using dynamic linking, whereas the DEV C++ is linking statically, hence the larger size and why one works and not the other.
However, if its a plain win32 application project you've got (and you don't want/need to distribute it with a setup), you may be able to get it to run on another machine without redistributing the CRT by getting VS2008 to link statically for you (if its just the standard lib you're missing). I don't have a copy of VS2008 to hand, so I'll describe how to do it in VS2005 and hopefully it'll translate across.
Bring up configuration properties for the project (right click the project name, then select "properties" from the menu)
Expand "Configuration Properties", then "C/C++", then click "Code Generation"
Under the "Runtime Library" item, for your particular configuration select the non-DLL version of the library i.e. for debug builds you want "Multi-threaded Debug (/MTd) and for release builds you want "Multi-threaded (/MT)"
Try and see if that works. You'll obviously get a much bigger final binary now the library is statically linked.
You may be missing an external dependency required by your program. Check the project settings to see if you are linking against MFC dynamically for example. You can also run Depends utility to check for missing dependencies.