Visual Studio , including CPP file inside other CPP - issues in existing project - winapi

I am trying to compile Microsoft Detours in Visual Studio 2013 ( not interested in compiling it through command prompt as suggested in many sites )
There is specific cpp file uimports.cpp which by itself will not compile since it does not have any headers but uses win api.
developers of detours including this file based on specific preprocessor definitions in other cpp file, logically since the file is copied as is there need not be any warning since all the win api required definitions exists in the other cpp file (e.g. creatwth.cpp):
#if DETOURS_32BIT
#define DWORD_XX DWORD32
#define IMAGE_NT_HEADERS_XX IMAGE_NT_HEADERS32
#define IMAGE_NT_OPTIONAL_HDR_MAGIC_XX IMAGE_NT_OPTIONAL_HDR32_MAGIC
#define IMAGE_ORDINAL_FLAG_XX IMAGE_ORDINAL_FLAG32
#define UPDATE_IMPORTS_XX UpdateImports32
#define DETOURS_BITS_XX 32
#include "uimports.cpp"
#undef DETOUR_EXE_RESTORE_FIELD_XX
#undef DWORD_XX
#undef IMAGE_NT_HEADERS_XX
#undef IMAGE_NT_OPTIONAL_HDR_MAGIC_XX
#undef IMAGE_ORDINAL_FLAG_XX
#undef UPDATE_IMPORTS_XX
#endif // DETOURS_32BIT
#if DETOURS_64BIT
#define DWORD_XX DWORD64
#define IMAGE_NT_HEADERS_XX IMAGE_NT_HEADERS64
#define IMAGE_NT_OPTIONAL_HDR_MAGIC_XX IMAGE_NT_OPTIONAL_HDR64_MAGIC
#define IMAGE_ORDINAL_FLAG_XX IMAGE_ORDINAL_FLAG64
#define UPDATE_IMPORTS_XX UpdateImports64
#define DETOURS_BITS_XX 64
#include "uimports.cpp"
#undef DETOUR_EXE_RESTORE_FIELD_XX
#undef DWORD_XX
#undef IMAGE_NT_HEADERS_XX
#undef IMAGE_NT_OPTIONAL_HDR_MAGIC_XX
#undef IMAGE_ORDINAL_FLAG_XX
#undef UPDATE_IMPORTS_XX
#endif // DETOURS_64BIT
I am missing some compiler flag that will hint visual studio to ignore errors in uimports.cpp. or any other logical solution beside redefining the headers in uimports.cpp just to help visual studio.

There are two possible solutions to this, assuming that uiImports.cpp is never supposed to be compiled "free-standing".
The first is to right click on the file in Solution Explorer, and select the "Exclude from Project" option. That will cause Visual Studio to remove it from the list of files, and it won't get compiled directly. The one downside to this is that it becomes harder to edit the file, since you can't just double click it in Solution Explorer to open it.
The other is a bit more messy, but keeps it in the solution, so it can easily be edited.
Place the following line at the top:
#ifndef DONT_COMPILE_ME
with a corresponding
#endif
at the bottom.
Then right click the file in Solution Explorer, hit properties, C/C++, Preprocessor, and add DONT_COMPILE_ME to the Preprocessor Definitions.

Related

Using DEBUG_NEW correctly

Can someone please clarify if I must add this code to the top of all my CPP files, or will it be sufficient if only one CPP file defines it?
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
You need to place this macro at the top of every translation unit1 for which you wish to track memory allocations. Macros are in effect from the point where they are defined to the end of the currently compiled translation unit (unless they are undefined prior to the end).
Also note that there's a __FILE__ macro involved, which already is a strong hint that the (non-compliant) replacement of new is per-file.
1 Translation units are the input to the compiler for which it generates object code. You can roughly think of a translation unit as a preprocessed source file (commonly with a file extension of .cpp, .cc, or .cxx).

Ignoring warnings in non-project files in Visual Studio

I just turned on all warnings (/Wall) and treat all warnings as errors (/WX). I suddenly went from 0 warnings to 1329 error-warnings.
The thing is, 99% of those warnings are not in files I've written. Part of them are in the standard library, while others are in libraries I'm using with my project.
How do I tell Visual Studio to perform this kinds of checks only for files that I've written (which are a part of the project directly) while ignoring everything else?
Note that all my own source files will be within a single folder, as will any library includes (but not the same as my source files).
EDIT:
I've realized I can wrap all includes I don't want checked between two pragmas, for example:
#pragma warning(push, 0) // Ignore warnings in non-project files.
#include "volk.h"
#include "glfw3.h"
#include <assert.h>
#include <cstdio>
#include <stdexcept>
#include <vector>
#pragma warning(pop);
However, in this case, I have several warnings present in file xmemory which are still being reported. They appear in function _Adjust_manually_vector_aligned, but I don't know where to go from here.
Note that this warning appears even if I wrap my whole (and only) file in the pragmas above.
While wrapping includes in #pragma warning(push, 0) and #pragma warning(pop); will work for flags W0 to W4, Wall seems to contain warnings that are not affected by the pragmas above. It is by design:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/891a02d2-d0cf-495a-bcea-41001cf599de/pragma-warningpush-0-cant-disable-wall-warning-on-visual-studio-2017?forum=vcgeneral

Error when including winuser.h. It defines ChangeMenu to ChangeMenuW or ChangeMenuA

Working on a Qt app on Windows. I include QVboxLayout in my source file only and this causes errors because its macro overwrites my method name.
foo.hpp
class foo
{
ChangeMenu();
}
foo.cpp
#include "foo.hpp"
#include "QVBoxLayout" // <--- this includes winuser.h
foo::ChangeMenu(){};
Now what happens is winuser.h has a macro
#ifdef UNICODE
#define ChangeMenu ChangeMenuW
#else
#define ChangeMenu ChangeMenuA
#endif // !UNICODE
This changes my function definition to ChangeMenuW but my declaration is still ChangeMenu.
How should I solve this? How can winuser.h define such a "normal" name as a macro?
Version of winuser.h is "windows kits\10\include\10.0.16299.0"
Pretty much any Windows API that deals with strings is actually a macro that resolves to a A or W version. There's no way around, you can either:
avoid including windows.h, but as you noticed, it creeps through;
brutally #undef the macro before defining/using your function; this is a fit punishment for hoarding such normal and non-macro-looking identifiers, but is tedious and some other code may actually need the Win32 function;
just accept it as a sad fact of life and avoid all the relevant Win32 APIs names; if you use Qt and follow its naming convention, it should be easy, as Qt functions use lowerCamelCase (as opposed to Win32 UpperCamelCase);
include windows.h explicitly straight in your header (possibly under an #ifdef _WIN32); this will make sure that your identifier will get replaced by the macro in all instances, so everything will work fine even if the compiler will actually compile a function with a different name; suitable for standalone projects, not suitable for libraries. (Thanks #Jonathan Potter for suggesting this)
You could take no care about this issue, Although your method name will be the same as the windows API, but the system will not mix them(just unify Unicode on both the place to define/call). If you call the ChangeMenu() directly, you will call the winapi, and if
foo f;
f.ChangeMenu();
or
foo::ChangeMenu();(static)
You will call your method.
And if you want to disable the winapi:
#ifdef ChangeMenu
#undef ChangeMenu
//code place that you define/call your own ChangeMenu().
#ifdef UNICODE
#define ChangeMenu ChangeMenuW
#else
#define ChangeMenu ChangeMenuA
#endif // !UNICODE
#endif
(It looks very tedious.)

What does #defining WIN32_LEAN_AND_MEAN exclude exactly?

I found the explanation defining WIN32_LEAN_AND_MEAN "reduces the size of the Win32 header files by excluding some of the less frequently used APIs". Somewhere else I read that it speeds up the build process.
So what does WIN32_LEAN_AND_MEAN exclude exactly? Should I care about this pre-processor directive? Does it speed up the build process?
I've also seen a pre-processor directive in projects named something along the lines of extra lean. Is this another esoteric pre-processor incantation I should know about?
According the to Windows Dev Center WIN32_LEAN_AND_MEAN excludes APIs such as Cryptography, DDE, RPC, Shell, and Windows Sockets.
Directly from the Windows.h header file:
#ifndef WIN32_LEAN_AND_MEAN
#include <cderr.h>
#include <dde.h>
#include <ddeml.h>
#include <dlgs.h>
#ifndef _MAC
#include <lzexpand.h>
#include <mmsystem.h>
#include <nb30.h>
#include <rpc.h>
#endif
#include <shellapi.h>
#ifndef _MAC
#include <winperf.h>
#include <winsock.h>
#endif
#ifndef NOCRYPT
#include <wincrypt.h>
#include <winefs.h>
#include <winscard.h>
#endif
#ifndef NOGDI
#ifndef _MAC
#include <winspool.h>
#ifdef INC_OLE1
#include <ole.h>
#else
#include <ole2.h>
#endif /* !INC_OLE1 */
#endif /* !MAC */
#include <commdlg.h>
#endif /* !NOGDI */
#endif /* WIN32_LEAN_AND_MEAN */
If you want to know what each of the headers actually do, typing the header names into the search in the MSDN library will usually produce a list of the functions in that header file.
Also, from Microsoft's support page:
To speed the build process, Visual C++ and the Windows Headers provide
the following new defines:
VC_EXTRALEAN
WIN32_LEAN_AND_MEAN
You can use them to reduce the size of the Win32 header files.
Finally, if you choose to use either of these preprocessor defines, and something you need is missing, you can just include that specific header file yourself. Typing the name of the function you're after into MSDN will usually produce an entry which will tell you which header to include if you want to use it, at the bottom of the page.
Complementing the above answers and also "Parroting" from the Windows Dev Center documentation,
The Winsock2.h header file internally includes core elements from the Windows.h header file, so there is not usually an #include line for the Windows.h header file in Winsock applications. If an #include line is needed for the Windows.h header file, this should be preceded with the #define WIN32_LEAN_AND_MEAN macro. For historical reasons, the Windows.h header defaults to including the Winsock.h header file for Windows Sockets 1.1. The declarations in the Winsock.h header file will conflict with the declarations in the Winsock2.h header file required by Windows Sockets 2.0. The WIN32_LEAN_AND_MEAN macro prevents the Winsock.h from being included by the Windows.h header ..
Here's a good answer on the motivation for it from Raymond Chen's blog:
https://devblogs.microsoft.com/oldnewthing/20091130-00/?p=15863
...defining WIN32_LEAN_AND_MEAN brought you back to the 16-bit Windows philosophy of a minimal set of header files for writing a bare-bones Windows program. This appeased the programmers who liked to micro-manage their header files, and it was a big help because, at the time the symbol was introduced, precompiled header files were not in common use. As I recall, on a 50MHz 80486 with 8MB of memory, switching to WIN32_LEAN_AND_MEAN shaved three seconds off the compile time of each C file. When your project consists of 20 C files, that’s a whole minute saved right there.

How to check if the current operating system is Windows, Linux, or OSX?

I'm writing a compiler project which will produce assembly code as the target language. However, there are some small changes that need to be accounted for depending on the operating system, and I'm not sure how to check for the OS. In case it matters, I am concerned with only 32bit. I've seen in some source code something like
#ifdef WIN32
but I have no idea how/if this works.
EDIT: Some clarification. I am using gcc on all three platforms. I don't know if macros like WIN32 are defined via gcc in each platform. If so, these constants seem to solve my issue.
The use of #ifdef uses preprocessor symbols to conditionally compile code depending on which symbols are defined. In your example, the compiler or an #include file may define WIN32, which means the code is being compiled in a Win32 environment.
Depending on the compiler and the platform, there may be different predefined symbols that indicate the operating system or processor architecture (among many other possible things) that relate to the current compilation environment.
With gcc, you can show the predefined symbols using the following command line:
gcc -E -dM - </dev/null
On my machine, one of the defined symbols is:
#define __FreeBSD__ 8
This happens to mean that I'm running FreeBSD version 8.
(The above applies to C and C-family languages such as C++.)
Generally the essential platform-determinign predefined macros are defined by the compiler itself, often depending on other switches.
Best way for a given compiler is to search for "predefined macros" or "predefined symbols" in their help. eg: googling visual studio predefined macros yields this page.
My OOFILE frameworks covered a wide range of systems. The oofplat.h is available from Sourceforge svn browser and unifies the different compiler definitions into _Windows etc.
Relevant portions copied below. Note that it's fairly ignorant when it comes to differentiating Unix versions as there weren't built-ins defined by the compiler.
#ifndef _Windows
#if defined(_WIN32)
#define _Win32
#define _Windows
#elif defined(WIN32)
#define _Win32
#define _Windows
#elif defined(__WIN32__)
#define _Win32
#define _Windows
#elif defined(__Win32__)
#define _Win32
#define _Windows
#elif defined(_WINDOWS)
#define _Windows
#elif defined(__INTEL__) && defined(__MWERKS__)
// Metrowerks CodeWarrior doesn't build anything other than Win32 on INTEL, no DOS
#define _Windows
#define _Win32
#endif
#else
#if defined __Win32__ || defined _WIN32
#ifndef _Win32
#define _Win32
#endif
#endif
#endif
#ifndef _MSDOS
#ifdef _Windows
#define _MSDOS
#elif defined(MSDOS)
#define _MSDOS
#elif defined(__MSDOS__)
#define _MSDOS
#endif
#endif
#ifdef _Windows
#ifndef STRICT
// some Windows headers define STRICT. In Visual C++ at least having it defined
// affects how static member signatures are mangled, so we define it up front
#define STRICT
#endif
#endif
// if not a DOS machine by now, may be Mac or Unix
// cope with Metrowerks and Symantec (and MPW?)
#ifndef _MSDOS
#ifndef _Macintosh
#ifdef macintosh
#define _Macintosh
#endif
#endif
#ifndef _Macintosh
#define _Unix
#endif
#endif
This is the power of the C preprocessors. First at all, you can define macros:
#define MY_MACRO
After this, you can check if a macro is defined:
#ifdef MY_MACRO
code, code, code
code, code, code
#endif
That means the code inside #ifdef and #endif blocks will be valid only if that macro was defined. Else it'll be ignored, and with ignored I mean it'll be like you haven't never written it.
The opposite of #ifdef is #ifndef. #endif is the same for both cases.
In your case, you can use macros in order to change what a function will do:
#define MY_MACRO
void my_function() {
#ifdef MY_MACRO
code_for_my_macro();
#endif
#ifdef ANOTHER_MACRO
code_for_another_macro();
#endif
}
..so the only thing you'll need to do to port your code is changing the macro.
Macros have more utilities. Search for "C preprocessors" and you'll see all what you can do with them.

Resources