简体   繁体   中英

Using curl in a Windows Universal App

I want to use curl in a Windows Universal App (x64).

I managed to get it working, but I had to use a workaround that seems hackish, and I want to confirm that it is needed.

TL;DR - I had to add an #include <winsock2.h> statement before the #include <curl\\curl.h> statement, to get it to work. I want to know if it's truly needed on UWP.

I built curl with openssl by following the curl install guide here . I created a blank universal app in Visual Studio 2015 update 3, and added curl and openssl binaries and includes in the appropriate places. Then added a #include <curl\\curl.h> at the top of the file and got the following error:

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int error C4430: missing type specifier - int assumed. Note: C++ does not support default-int for the line typedef SOCKET curl_socket_t; in curl.h .

At the top of curl.h I saw that the following preprocessor macros prevent the inclusion of winsock2.h which defines SOCKET :

#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \
      defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
/* The check above prevents the winsock2 inclusion if winsock.h already was
   included, since they can't co-exist without problems */
    #include <winsock2.h>
    #include <ws2tcpip.h>
#endif

Removing the defined(_WINSOCKAPI_) condition restores the statement and everything compiles fine, meaning that somewhere winsock.h is included and that on UWP it does not defined SOCKET .

Indeed, looking at winsock.h I can see that the typedef which defines SOCKET is wrapped with

#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)

which does not hold for a universal app.

However, in winsock2.h there's an equivalent typedef for SOCKET which is not dropped by the preprocessor.

Adding #include <winsock2.h> before the #include <curl\\curl.h> statement makes everything work, but I suspect this is not the best way to solve this issue.

So my question is, is this the proper way to use curl on UWP or has anyone found a better solution?

Thanks!

Generally it should be no problem to include <winsock2.h> before <curl/curl.h>. But you're also right that it should work without that, because curl.h should include that file if necessary. As it does not in your case, _WINSOCKAPI_ must be defined somewhere else. Perhaps it's defined in the preprocessor area of the project settings, ie it is provided via /D compiler flag. Did you already look there? Also look at the compiler command line, that is used to compile your file, is there a flag that defines _WINSOCKAPI_?

BTW, the reason why curl includes <winsock2.h> conditionally is as follows: Windows has two different socket libraries, winsock and winsock2 (which is to prefer). Both cannot coexistent with each other. If you need to use winsock instead of winsock2 for some reason you may include <winsock.h> before <curl/curl.h>, and it will work as well.

I confirmed that winsock.h is being included by the following include chain: pch.h > collection.h > agile.h > wrl\\client.h > unknwn.h > rpc.h > windows.h > winsock.h . pch.h is generated by Visual Studio, and is part of the Universal blank app template.

My workaround is not ideal because this will get winsock.h and winsock2.h both included, and the comment in curl.h says they can't co-exist.

However, I did find that in windows.h , the inclusion of winsock.h is wrapped with #ifndef WIN32_LEAN_AND_MEAN , ie, I can prevent winsock.h from being included by adding the WIN32_LEAN_AND_MEAN define.

I tried it and successfully issued a simple https request from a UWP app.

So to summarize - when using curl in a UWP app, you must add the preprocessor definition WIN32_LEAN_AND_MEAN .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM