Boost::asio winsock and winsock 2 compatibility issue - c++

My project uses windows.h in which winsock.h is used, and I need to include boost:assio which uses winsock2. So I get many errors that says Winsock.h already included.
I can define WIN32_LEAN_AND_MEAN. so that windows.h wouldn't use winsock. The problem is , that I need windows.h to use it, and I just need Asio for asynchronous timers. I don't need its winsock2.h . I tried searching how to disable its winsock2 use, and I found that I could do that by defining BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN before including boost:asio, but I still get the same error.
#include <windows.h>
#define BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN
#include <boost/asio.hpp>
Error
1>c:\program files\boost\boost_1_47\boost\asio\detail\socket_types.hpp(22): fatal error C1189: #error : WinSock.h has already been included

Try and change the order of includes. Start with boost/asio.hpp and put windows.h after it.
Usually the writers of any code library solve the compatibility issues but they can do it better if their code is the first to meet the compiler and preprocessor.
There's a similar issue with ACE, including ace/OS.h before anything else solves it.

As Danius (the OP) points out a compile with
#include <windows.h>
#include <boost/asio.hpp>
fails with this error:
1>c:\source\<SNIP>\boost\1.51.0\boost\asio\detail\socket_types.hpp(22): fatal error C1189: #error : WinSock.h has already been included
On the other hand
#include <boost/asio.hpp>
#include <windows.h>
Produces a bunch of noise and sets the windows version # incorrectly
1? Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
1> - add -D_WIN32_WINNT=0x0501 to the compiler command line; or
1> - add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
1> Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
I couldn't find any way around this that didn't leave a bad taste, but this:
#ifdef _WIN32
# ifdef USE_ASIO
// Set the proper SDK version before including boost/Asio
# include <SDKDDKVer.h>
// Note boost/ASIO includes Windows.h.
# include <boost/asio.hpp>
# else // USE_ASIO
# include <Windows.h>
# endif // USE_ASIO
#else // _WIN32
# ifdef USE_ASIO
# include <boost/asio.hpp>
# endif // USE_ASIO
#endif //_WIN32
Does produce a clean compile.
<EDITORIAL> It shouldn't be that hard </EDITORIAL>

For me, switching the order of includes caused compile errors with another Microsoft include I was using - that was declaring things with "typedef interface".
Since my error was coming from socket_types.h, from these lines:
# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
# error WinSock.h has already been included
# endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
I put an include of "winsock2.h" before the Windows.h, and then finally the boost/asio.hpp include, and things then compiled happily.

#ifdef BOOST_OS_WINDOWS
#define _WIN32_WINNT 0x0501
#if _WIN32_WINNT <= 0x0501
#define BOOST_ASIO_DISABLE_IOCP
#define BOOST_ASIO_ENABLE_CANCELIO
#endif
#endif

An other workarround I used is to concentrate all asio dependent
code in an XXX.hpp file and include it on the top of each windows implementing
XXX.cpp file where you use its objects.
this method place the include asio above any other include windows.h and work arround the problem.

Related

Unexpected #else

For some reason I can't explain, the compiler is outputting an error saying that it found an unexpected #else token.
This occurs at the beginning of the file :
#if defined( _USING_MFC )
#include "stdafx.h"
#else
#include <windows.h>
#endif
There is nothing before that peice of code expect several (single-line) comments.
This error occurs in a .cpp file. What you see above is the beginning of the file. There is nothing before that.
I tried adding the following code before the code defined above, and the error is now an unexpected #endif
#if 1
#include "stdafx.h"
#endif
So I suspect there is an issue with the included stdafx.h file which contains the following code :
#ifndef STDAFX_H_INCLUDED
#define STDAFX_H_INCLUDED
#include <Afx.h>
#include <Windows.h>
using namespace ATL;
#endif // STDAFX_H_INCLUDED
There's really nothing special about it. I'm also including this stdafx.h file from a stdafx.cpp file that only contains the #include statement, and it compiles correctly.
Here are the project preprocessor definitions :
_DEBUG
_WIN32_WCE=$(CEVER)
UNDER_CE
WINCE
DEBUG
_WINDOWS
$(ARCHFAM)
$(_ARCHFAM_)
_UNICODE
UNICODE
_TERMINAL_FALCONX3_CE6
_NO_CPP_EXCEPTIONS
_DONT_INCLUDE_WS_HEADERS
_USING_MFC
And some extra informations :
Compiling for Windows CE 6 using Visual Studio 2008.
What would be causing this ? Thank you.
Based on the name stdafx, I assume it is a precompiled header.
A precompiler header must be the first include (preprocessor) directive in the file, you can't put anything (not even an ifdef) before it. The only exception being a few comment lines, as those would be ignore anyway.
Based on your example, you should put the #ifdef _USING_MFC into your stdafx.h, and include Afx.h there.

How to check if MS compiler will compile my source code

Guys I was trying in VS to do something like:
#ifdef _MSC_VER
#include "stdafx.h"
#endif
but I'm getting an error telling me:
C1020: unexpected #endif
What is the correct way to do it?
Edit
/This is content of stdafx.h/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
//#include <stdio.h>
//#include <tchar.h>
#include <iostream>
using std::cout;
using std::cerr;
// TODO: reference additional headers your program requires here
You cannot put conditionals around stdafx.h because of the way MSVC precompiled headers work. It basically replaces everything once stdafx.h has been found (and usually requires #include "stdafx.h" to be the first line in the file) with the precompiled header contents, so it is as if you never wrote #if _MSC_VER and have an extra #endif.
Two solutions:
1) Do not use precompiled headers in your project. You can still use stdafx.h to include all the headers you require but compilation will be slow.
2) Put the conditional compile within the stdafx.h file.
(Taken from here)

Where is WIN32 defined, and how can I include this definition in my project?

I am including a third party header and source file into my project.
At the top of the header there is this:
#if defined(WIN32) || defined(WIN16)
#ifndef MSDOS
#define MSDOS
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#ifndef MSDOS
#include <unistd.h>
#endif
#include "des.h"
The problem is that #if defined(WIN32) fails and the compilation fails when trying to #include unistd.h which I don't want to do.
I have third party project that works with this header file i.e. WIN32 is defined and it doesn't try to include In Visual Studio I did "Go To Definition" on "WIN32" and was taken to the following definition in WinDefs.h.
#define WIN32
I'm not sure this is where its getting WIN32 definition from, as the third party project does not appear to include "WinDefs.h".
So my problem is, how can I get WIN32 to be defined in my current new project?
Depends on your project setup. WIN32 is defined inside the windows header files, but you can pass it to the compiler as well ("-DWIN32" for gcc for example). Try it and see whether it compiles.
Visual Studio has the built-in define _WIN32. mingw-gcc has WIN32 and _WIN32 built-in so the project was likely tested using gcc. You might add
#if defined(_WIN32) && !defined(WIN32)
#define WIN32
#endif
or just add a -DWIN32 to the CFLAGS.
Check your includes. I am guessing that the third party header is included prior to the windows.h. So, in your main.cpp or equal it should be
#include <windows.h> // this will also include windefs.h
#include <thirdParty.h>
and not the other way around.
Hope that helps.
You can simply include the windows header files (windows.h) before including the third party header - as you already found out WIN32 is defined there but technicaly it could be defined anywhere (so if the third party project is not including the windows headers check if it's being defined in the compiler project settins directly).
BTW there is also a _WIN32 define that is set by the compiler, it's possibly a better idea to look for this define if checking if the code is being compiled under windows;
For those seeking answers to the
where is WIN32 defined
part of the questions, I've found it defined in:
minwindef.h
ole2.h
Note, I have no confidence that these are the only places it's defined. I expect there are probably other files where it's defined. Nevertheless, I thought this might help some people.
Some WIN32 defined in the compiler . Just like this,If you use the gcc for windows , WIN32 is defined . If you use the gcc for linux , WIN32 is not defined :)
So , the macros is a switch. You can define it to use somethine , and not define it to unuse something.

JRTPLIB/header include problem

I'm having some problems with JRTPLIB c++ win32 version, compiling in visual studio2010.(http://research.edm.uhasselt.be/~jori/page/index.php?n=CS.Jrtplib). I've emailed the author but have yet to received a reply. The problem I am experiencing is this:
error C1083: Cannot open include file: 'rtpconfig_unix.h': No such file or directory c:\users\johan-bar\desktop\developer tools\3rd party software\jrtplib-3.8.1\src\rtpconfig.h
The two .h files I have are these:
MAIN.h:
enter code here
#include <WinSock2.h>
#include <Windows.h>
#include <WindowsX.h>
#include <stdlib.h>
#include <string>
#include <Richedit.h>
#include "jrtlibtest.h"
#include "resource.h"
jrtlibtest.h:
#include "rtpsession.h"
So I reason that I need to #include windows.h in jrtlibtest.h for it to recognise WIN32 to be defined (so it does not include unix .h files) but that in turn gives me about 100 redifinition errors.
I am unsure how to solve this problem and I can't find any information on the library homepage itself or on the internet. Has anyone else encountered this problem?
Cheers
I have not seen JRTPLIB c++ lib, but based on information that you provided ('rtpconfig_unix.h'can not be opened), it seems that it is taking default file for unix port? Look for something like a config file in the JRTPLIB folder and run it (./config on cygwin or something). That should generate the windows config files that you would be able to #include in your code.
Good luck!!
EDIT:
The fact that you are getting the error:
error C1083: Cannot open include file: 'rtpconfig_unix.h':
means: in your rtpconfig.h, the WIN32 macro is not enabled:
#ifndef RTPCONFIG_H
#define RTPCONFIG_H
#if (defined(WIN32) || defined(_WIN32_WCE))
#include "rtpconfig_win.h"
#else
#include "rtpconfig_unix.h"
#endif // WIN32
//#define RTPDEBUG
#endif // RTPCONFIG_H
And thatś why it says it cant open rtpconfig_unix.h file.
Did you try #defining win32 macro in rtpconfig.h directly? (or do it in your project settings).
Include ws2_32.lib in your project. Had the same problem.
(And remove if you already include it, wsock32.lib and winsock.h header file to avoid colissions)
What are the redefinition errors?
If they are from winsock, removing winsock2.h from your includes might help.

include of header with ifdef

I've tried placing the following in my C++ code:
#ifdef _WIN32
#include "stdafx.h"
#endif
but I getan error:
PCH warning: header stop cannot be in a macro of #if block. An IntelliSense PCH file was not generated.
I'm trying to let my code work both on windows and linux, stdafx.h does not work on linux where it's a must on visual studio.
Is there another way to use the include with ifdef?
Unfortunately you can not do that with precompiled header and using Microsoft MSVC. The MSVC totally ignores all code (and whatever garbage) lines that precede that #include "stdafx.h" line. As result the #endif will be unexpected to it.
Put that #ifdef _WIN32 and what not inside of stdafx.h.
I have just created an empty stdafx.h. With follow content for solutions without pre-compiled headers
#pragma once
//this is only for using Common modules with Precompiled headers. We can't disable it using a preprocessor(
//https://stackoverflow.com/a/36271896/6160632