web-dev-qa-db-fra.com

Problème de compatibilité avec Boost :: asio winsock et winsock 2

Mon projet utilise windows.h dans lequel winsock.h est utilisé et je dois inclure boost: assio qui utilise winsock2. Je reçois donc beaucoup d'erreurs disant que Winsock.h est déjà inclus. Je peux définir WIN32_LEAN_AND_MEAN. afin que windows.h n'utilise pas Winsock. Le problème, c’est que j’ai besoin de windows.h pour l’utiliser et d’Asio pour les timers asynchrones. Je n'ai pas besoin de son winsock2.h. J'ai essayé de chercher comment désactiver son utilisation de winsock2, et j'ai découvert que je pouvais le faire en définissant BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN avant d'inclure boost: asio, mais j'obtiens toujours la même erreur.

#include <windows.h>
#define BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN
#include <boost/asio.hpp>

Erreur

1> c:\programmes\boost\boost_1_47\boost\asio\detail\socket_types.hpp (22): erreur irrécupérable C1189: #error: WinSock.h a déjà été inclus

17
Dainius Kreivys

Essayez de changer l'ordre ou comprend. Commencez avec boost/asio.hpp et mettez windows.h après.

Généralement, les rédacteurs de n'importe quelle bibliothèque de code résolvent les problèmes de compatibilité, mais ils peuvent le faire mieux si leur code est le premier à rencontrer le compilateur et le pré-processeur.

Il existe un problème similaire avec ACE, y compris ace/OS.h, avant qu’aucune autre solution ne le résolve.

21
selalerer

Comme Danius (l’OP) fait remarquer une compilation avec

#include <windows.h>
#include <boost/asio.hpp>

échoue avec cette erreur:

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

D'autre part

#include <boost/asio.hpp>
#include <windows.h>

Produit beaucoup de bruit et ne définit pas correctement la version de Windows

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).

Je n'ai trouvé aucun moyen de contourner cela sans laisser de mauvais goût, mais ceci:

#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

Produit une compilation propre.

<EDITORIAL> Cela ne devrait pas être si difficile </ EDITORIAL>

10
Dale Wilson

Pour moi, changer l'ordre d'inclusions a causé des erreurs de compilation avec un autre Microsoft include que j'utilisais - qui déclarait des choses avec "interface typedef".

Puisque mon erreur venait de socket_types.h, à partir de ces lignes:

# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
#  error WinSock.h has already been included
# endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)

Je mets une inclusion de "winsock2.h" avant Windows.h, puis enfin le boost/asio.hpp, et les choses sont ensuite compilées avec bonheur.

8
Theanderblast

Une autre solution que j’ai utilisée consiste à concentrer tout le code dépendant d’asio dans un fichier XXX.hpp et à l’inclure au-dessus de chaque fenêtre implémentant le fichier XXX.cpp où vous utilisez ses objets.

cette méthode place l'include asio au-dessus de toute autre inclure windows.h et corrige le problème.

0
ori
#ifdef BOOST_OS_WINDOWS
#define _WIN32_WINNT 0x0501
#if _WIN32_WINNT <= 0x0501
#define BOOST_ASIO_DISABLE_IOCP
#define BOOST_ASIO_ENABLE_CANCELIO
#endif
#endif
0
William H Myatt