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

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.

Related

error LNK1181: cannot open input file 'kernel32.lib'

I have a project on VS 2012. latest SDK is installed on the WIN 8 x64 computer, the project is targeting WIn32.
I have a clean build in Debug, but when I go to release I get the 1181 LNK error - cannot open input file kernel32.lib.
I have the file on the computer in several location, and in the VC directories there is $(WindowsSdkDir_71A)lib and $(WindowsSdkDir)\lib.
Using process monitor I've tried to rebuild and see where devenv.exe is looking for the file
** UPDATE:
In debug it looks in the right place.
in release it doesn't look for the sdk,
but I see this:
Y:\MyProjectFofler\$(LibraryPath)\kernel32.lib PATH NOT FOUND
and also several successful reads from the win8.0 sdk (which should be ok, but the result is the same, and I need it to read from the V7.1A SDK folder...)
What can it be and what might be the solution for this error ?
Thanks.
I ran into this using Visual Studio 2017. I was trying to get the Visual Studio project configurations to reference the external library .lib files I wanted. I managed to trigger this error when I removed any reference to the system libraries. I later figured out this can be corrected by including one of their macro values (though you can specify an absolute direct path, but that's probably not the best coding convention and prone to brittleness).
On the Visual Studio project, right-Clicking on the project item in the Solution explorer panel (not the Solution itself, which is the topmost item), then select Properties. From there do the following:
VC++ Directories --> Library Directories : $(ProjectDir)lib; $(LibraryPath)
Note the $(LibraryPath) value will include extra values such as inherited from parents, and from what I can tell this is a verbose option. My folder project contained a folder called 'lib' which is why I had the first value there before the semicolon.
There are other common options I have used to specify the Library Directories value:
$(VC_LibraryPath_x86)
$(WindowsSDK_LibraryPath_x86)
$(NETFXKitsDir)Lib\um\x86
If you look at the section VC++ Directories --> Library Directories, you can click on the entry line and select 'Edit', then you can watch live previews of what Macros values will be evaluated and resolved to. If you need additional or more specialized values, click on the Macros button to look for more options.
Link to image of Visual Studio 2017 Library Directories configuration

What to do next after building wxWidgets successfully : Visual Studio 2010

I have downloaded c++ open source application which was created using under Linux IDE/Editor (or maybe something NOT Windows) and its no longer supported.
This time I want to edit and recompile it using VS 2010.
Error(s) left (mostly prefixed with "wx") such as:
"wxString is undefined"
"wxStaticText expected a type specifier"
etc... makes me think that this is all about wxWidgets.
After successfully building wxWidgets, what to do next to integrate it to the actual c++ program for me to be able to edit and compile using VS 2010?
I use BorlandC++ last 2 years ago but not familiar with GUI packages.
The first step is to tell the compiler where to look for the wxWidgets include files.
So, you need to find out where these files are, which depends on where you installed and built wxWidgets.
On my system, this is C:\Program Files (x86)\wxWidgets-2.8.12
I consider the best way is to, instead of hard-coding the path in every project, create an environment variable WXROOT to store the path to your wxWidgets folder.
Control Panel | System | Advanced | Environment variables
Now you have to tell the compiler about this
Visual Studio | Project | Properties | C/C++ | Additional Include Directories
What you add here depends on what kind of build you are doing. If you are doing a unicode release build, then this will be a good start
"$(WXROOT)\lib\vc_lib\mswu";"$(WXROOT)\include"
Now you should have fixed your compiler errors.
Next you will get some linker errors ....
Maybe the errors are caused because you are using wxwidget 2.8 which is unsupported in VS 2010.
Try building wxwidgets 2.9 or use VS 2008. I had no problem building wxwidgets 2.9 on VS 2010.
Wxwidgets site home says "While this is still officially a development release because some API details are still not frozen, we believe that 2.9.3 can be used in production environment".
About what to do after successfully build it, take a look at this http://wiki.wxwidgets.org/Microsoft_Visual_C%2B%2B_Guide
You may want to use the tutorial of the section "Creating a new project from a sample" 'cause creating a project by hand is a little bit complicated as wxwidgets requires some extra configuration and not just to set and include and libs dir as most of the libs does.
Here is a video which shows how to start with Visual Studio.
Also you can take a look at samples directory and create your own project based on configuration of projects from that directory.
May be I am little bit late , But this will help newcomers to wxwidgets.
First of all Goto Wxwidgets directory(to download path) in my case it is "C:\Users\WxWidgets_all".
Now in that folder goto build directory.Now open Visual Studio Command prompt. If you have already installed Visual Studio then you can easily find it through start menu.
Now in command prompt go upto <Path to your wxWidgets>/build/msw/ . Now run Following Commands.
nmake /f makefile.vc--For Static Library and Debug Version
nmake /f makefile.vc SHARED=1--For SHARED Library and Debug Version
nmake /f makefile.vc BUILD=release--For SHARED Library and Release Version
After completing it , you will have dll or lib in "<path to wxwidgets>\lib\" depending on option provided in above commands.
Now include all files related to wxwidgets in your project.Mainly two paths are required to include "<path to wxwidgets>\inlcude\" and "<path to wxwidgets>\lib\vc_<lib\dll>".
After that link your wxwidgets generated library to your project.To do this inlcude "<path to wxwidgets>\lib\vc_<lib\dll>" to your project property in library section.
Now add below preprocessors to your project.
_WINDOWS
NDEBUG(For Release)
_DEBUG(For Debug)
_CRT_SECURE_NO_DEPRECATE=1
_CRT_NON_CONFORMING_SWPRINTFS=1
_SCL_SECURE_NO_WARNINGS=1
__WXMSW__
_UNICODE
After that add following library to your project from "<path to wxwidgets>\lib\vc_<lib\dll>"
wxbase30u_net
wxmsw30u_core
wxbase30u
wxtiff
wxjpeg
wxpng
wxzlib
wxregexu
wxexpat
wxmsw30u_adv
Based on your compiled options , library name can be little bit different.
I think I have covered all the steps to run wxWidgets.
Even if you got errors , You can check minimal project in "<path to wxwidgets>\samples"
directory. Try to run that project , and even if you got error then your wxwidgets is not built properly.
Hope this will help.

How do I start a new CUDA project in Visual Studio 2008?

This is an incredibly basic question, but how do I start a new CUDA project in Visual Studio 2008? I have found tons and tons of documentation about CUDA related matters, but nothing about how to start a new project. I am working with Windows 7 x64 Visual Studio 2008 C++. I would really like to find some sort of really really basic Hello World app to just get a basic program compiling and running.
Edit:
I tried your steps Tom. I setup a console app. I then deleted the default .cpp it drops in and copied over the three files from the template project just to have something to compile. When I compile that, template_gold.cpp complained about not having stdafx.h included, so i included that. Now the build fails with this:
1>------ Build started: Project: CUDASandbox, Configuration: Debug x64 ------
1>Compiling...
1>template_gold.cpp
1>Linking...
1>LIBCMT.lib(crt0.obj) : error LNK2019: unresolved external symbol main referenced in function __tmainCRTStartup
1>D:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\x64\Debug\CUDASandbox.exe : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://d:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\CUDASandbox\x64\Debug\BuildLog.htm"
1>CUDASandbox - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
NOTE With the release of version 3.2 of the CUDA Toolkit, NVIDIA now includes the rules file with the Toolkit as opposed to the SDK. Therefore I've split this answer into two halves, use the correct instructions for your version of the Toolkit.
NOTE These instructions are valid for Visual Studio 2005 and 2008. For Visual Studio 2010 see this answer.
CUDA TOOLKIT 3.2 and later
I recommend using the NvCudaRuntimeApi.rules file (or NvCudaDriverApi.rules if using the driver API) provided by NVIDIA, this is released with the toolkit and supports the latest compiler flags in a friendly manner. Personally I would advise against using the VS wizard, but only because I really don't think you need it.
The rules file (installed into the Program Files\Microsoft Visual Studio 9.0\VC\VCProjectDefaults directory) "teaches" Visual Studio how to compile and link any .cu files in your project into your application.
Create a new project using the standard MS wizards (e.g. an empty console project)
Implement your host (serial) code in .c or .cpp files
Implement your wrappers and kernels in .cu files
Add the NvCudaRuntimeApi.rules (right click on the project, Custom Build Rules, tick the relevant box), see note 1
Add the CUDA runtime library (right click on the project and choose Properties, then in Linker -> General add $(CUDA_PATH)\lib\$(PlatformName) to the Additional Library Directories and in Linker -> Input add cudart.lib to the Additional Dependencies), see notes [2] and [3]
Optionally add the CUDA include files to the search path, required if you include any CUDA files in your .cpp files (as opposed to .cu files) (right click on the project and choose Properties, then in C/C++ -> General add $(CUDA_PATH)\include to the Additional Include Directories), see note [3]
Then just build your project and the .cu files will be compiled to .obj and added to the link automatically
Some other tips:
Change the code generation to use statically loaded C runtime to match the CUDA runtime; right click on the project and choose Properties, then in C/C++ -> Code Generation change the Runtime Library to /MT (or /MTd for debug, in which case you will need to mirror this in Runtime API -> Host -> Runtime Library), see note [4]
Enable syntax highlighting using the usertype.dat file included with the SDK, see the readme.txt in <sdk_install_dir>\C\doc\syntax_highlighting\visual_studio_8
I'd also recommend enabling Intellisense support with the following registry entry (replace 9.0 with 8.0 for VS2005 instead of VS2008):
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Languages\Language Services\C/C++]
"NCB Default C/C++ Extensions"=".cpp;.cxx;.c;.cc;.h;.hh;.hxx;.hpp;.inl;.tlh;.tli;.cu;.cuh;.cl"
Incidentally I would advocate avoiding cutil if possible, instead roll your own checking. Cutil is not supported by NVIDIA, it's just used to try to keep the examples in the SDK focussed on the actual program and algorithm design and avoid repeating the same things in every example (e.g. command line parsing). If you write your own then you will have much better control and will know what is happening. For example, the cutilSafeCall wrapper calls exit() if the function fails - a real application (as opposed to a sample) should probably handle the failure more elegantly!
CUDA TOOLKIT 3.1 and earlier
I would use the Cuda.rules file provided by NVIDIA with the SDK, this is released alongside the toolkit and supports the latest compiler flags in a friendly manner. Personally I would advise against using the VS wizard, but only because I really don't think you need it.
The rules file (in the C\common directory of the SDK) "teaches" Visual Studio how to compile and link any .cu files in your project into your application.
Create a new project using the standard MS wizards (e.g. an empty console project)
Implement your host (serial) code in .c or .cpp files
Implement your wrappers and kernels in .cu files
Add the Cuda.rules (right click on the project, Custom Build Rules, browse for the rules file and ensure it is ticked)
Add the CUDA runtime library (right click on the project and choose Properties, then in Linker -> General add $(CUDA_LIB_PATH) to the Additional Library Directories and in Linker -> Input add cudart.lib to the Additional Dependencies), see note [2] below
Optionally add the CUDA include files to the search path, required if you include any CUDA files in your .cpp files (as opposed to .cu files) (right click on the project and choose Properties, then in C/C++ -> General add $(CUDA_INC_PATH) to the Additional Include Directories)
Then just build your project and the .cu files will be compiled to .obj and added to the link automatically
Some other tips:
Change the code generation to use statically loaded C runtime to match the CUDA runtime, right click on the project and choose Properties, then in C/C++ -> Code Generation change the Runtime Library to /MT (or /MTd for debug, in which case you will need to mirror this in CUDA Build Rule -> Hybrid CUDA/C++ Options), see note [4]
Enable syntax highlighting using the usertype.dat file included with the SDK, see the readme.txt in <sdk_install_dir>\C\doc\syntax_highlighting\visual_studio_8
I'd also recommend enabling Intellisense support with the following registry entry (replace 9.0 with 8.0 for VS2005 instead of VS2008):
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Languages\Language Services\C/C++]
"NCB Default C/C++ Extensions"=".cpp;.cxx;.c;.cc;.h;.hh;.hxx;.hpp;.inl;.tlh;.tli;.cu;.cuh;.cl"
Incidentally I would advocate avoiding cutil if possible, instead roll your own checking. Cutil is not supported by NVIDIA, it's just used to try to keep the examples in the SDK focussed on the actual program and algorithm design and avoid repeating the same things in every example (e.g. command line parsing). If you write your own then you will have much better control and will know what is happening. For example, the cutilSafeCall wrapper calls exit() if the function fails - a real application (as opposed to a sample) should probably handle the failure more elegantly!
NOTE
You can also use a Toolkit-version-specific rules fule e.g. NvCudaRuntimeApi.v3.2.rules. This means that instead of looking for the CUDA Toolkit in %CUDA_PATH% it will look in %CUDA_PATH_V3_2%, which in turn means that you can have multiple versions of the CUDA Toolkit installed on your system and different projects can target different versions. See also note [3].
The rules file cannot modify the C/C++ compilation and linker settings, since it is simply adding compilation settings for the CUDA code. Therefore you need to do this step manually. Remember to do it for all configurations!
If you want to stabilise on a specific CUDA Toolkit version then you should replace CUDA_PATH with CUDA_PATH_V3_2. See also note 1.
Having mismatched version of the C runtime can cause a variety of problems; in particular if you have any errors regarding LIBCMT (e.g. LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs) or multiply defined symbols for standard library functions, then this should be your first suspect.
What a great question!! For all the CUDA documentation out there, this is something that I've always thought was an obvious omission... In fact, I'm really glad I found this post, because after using CUDA for quite a while, I still hadn't found an official, correct way to get VS to produce a CUDA program from scratch.
When I've needed to start a new CUDA program, I've always just copied and modified the "template" example from the SDK directory. This may not be exactly what you're looking for, because it doesn't start fresh, but it is a quick way to get a CUDA-capable project working in VS with all the correct project/file names...
Make a copy of the "template" example from the SDK, and rename the directory -- the only necessary contents in the directory are source code and VS .sln and .vcproj files
Rename both .sln and .vcproj files
Open the .sln file in a text editor, and rename the Project variable and .vcproj filename in the 3rd line of the file
Open the .vcproj file in a text editor, and rename the Name and RootNamespace variables in the first few lines of the file
Open the project with VS, and open the Property Pages (right click on the project name in the solution explorer pane, select "Properties")
Change the Output File name in the Property Pages (under Configuration Properties -> Linker -> General) ... Before I change the filename, I select "All Configurations" from the Configuration pull-down and "x64" from the Platform pull-down, since I'm on a 64-bit system
Change the Program Database File name in the Property Pages (under Configuration Properties -> Linker -> Debugging) ... Before I change the filename, I select "Debug" and "x64" in the pull-downs.
Install CUDA VS wizard. It will setup VS and add CUDA Project to the "new project" menu.
Make sure that you have x64 compiler installed (must be checked during VS install).
Check if you have x64 libs, includes, nvcc dir and in the search path.
Create new project using CUDA template.
Change project type to x64 and CUDA setting to Native (if you have nv cuda-enabled card) or emulation otherwise.
The template will create custom build rules that compile .cu files with nvcc and other files with default compiler.
if, vs is trying to compile .cu files with C/C++ compiler, click on that file in solution explorer and disable compilation for that files (red dot on file's icon)
Additional info about installing CUDA wizard on VS2008 can be found here and here
[edit]
If you don't want to use wizard you have to setup CUDA lib/include/nvcc paths manually and add custom build rules to each new CUDA program. For additional info how to do it take a look at Tom's Answer.
You may want to take a look at this guide: http://www.programmerfish.com/how-to-run-cuda-on-visual-studio-2008-vs08/

How to make a single static library from multiple static libraries?

We recently converted a C++ project from Visual Studio 6 to Visual Studio 8. Everything went well until we reached the compilation of a project who put all the static libraries inside one big static library. By default after the conversion between the two version of projects the project didn't do anything (no big static library was created, it only said that the project was up-to-date).
We found a working solution by adding a dummy (empty) file to the project (it had no other files before, in the Visual Studio 6 solution). Everything went well and we managed to compile the project with the new development environment (Visual Studio 8).
My question is: Is there any other way to do this, without dummy files added to the project?
Thanks in advance for your responses
You can use the method described in the answer by nobugz also with multiple configurations and different directories for debug and release input libs. Just add all input libs, debug and release, and use "exclude from build". In the debug configuration exclude all release input libs from the build, in the release configuration exclude all debug input libs.

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.