背景

由于c++项目需要通过https请求与后台通信,于是找到了curl这个c++开源库。

地址:https://curl.se/libcurl/

需要支持Windows平台和Linux系统,于是,先尝试在Windows上安装。

 使用vcpkg工具安装

curl提供vcpkg的安装方式。这是首次使用vcpkg。上手如下:

1. 在E盘创建目录,vcpkg。进入cppkg目录。

2. 从githup上下载vcpkg工具,下载地址:git clone https://github.com/Microsoft/vcpkg.git

3. 进入vcpkg的目录,执行:

bootstrap.exe

自行完后,会生成 vcpkg.exe.

4. 在安装curl执行,先查看提供的curl库。

e:\vcpkg\vcpkg-master>vcpkg.exe search curl
azure-core-cpp[curl]                      Libcurl HTTP transport implementation
cfitsio[curl]                             UseCurl
cocoyaxi[libcurl]                         libcurl with OpenSSL support
configcat[network]                        Use built-in curl network adapter
cpr                      1.10.5#2         C++ Requests is a simple wrapper around libcurl inspired by the excellent ...
cpr[ssl]                                  Enable SSL support
curl                     8.7.1            A library for transferring data with URLs
curl[brotli]                              brotli support (brotli)
curl[c-ares]                              c-ares support
curl[http2]                               HTTP2 support
curl[idn]                                 Default IDN support
curl[idn2]                                idn2 support (libidn2)
curl[ldap]                                LDAP support
curl[mbedtls]                             SSL support (mbedTLS)
curl[non-http]                            Enables protocols beyond HTTP/HTTPS/HTTP2
curl[openssl]                             SSL support (OpenSSL)
curl[schannel]                            SSL support (Secure Channel)
curl[sectransp]                           SSL support (sectransp)
curl[ssh]                                 SSH support via libssh2
curl[ssl]                                 Default SSL backend
curl[sspi]                                SSPI support
curl[tool]                                Builds curl executable
curl[websockets]                          WebSocket support (experimental)
curl[winidn]                              WinIDN support
curl[winldap]                             Obsolete. Use feature 'ldap' instead.
curl[winssl]                              Legacy name for schannel
curl[wolfssl]                             SSL support (wolfSSL)
curl[zstd]                                ZStandard support (zstd)
curlpp                   2018-06-15#9     C++ wrapper around libcURL
czmq[curl]                                Build with libcurl
gdal[curl]                                Enable CURL network support
juce[curl]                                Enable CURL support
libcurl-simple-https     2022-02-14       Very simple HTTPS interface built atop libcurl
librdkafka[curl]                          Build with curl
oatpp-curl               1.3.0#1          Oat++ Modern web framework curl module to use libcurl as a RequestExecutor...
poppler[curl]                             curl for poppler
restclient-cpp           2022-02-09       Simple REST client for C++. It wraps libcurl for HTTP requests.
vsgxchange[curl]                          Enable support for reading image and model files from http:// and https://
The result may be outdated. Run `git pull` to get the latest results.
If your port is not listed, please open an issue at and/or consider making a pull request.  -  https://github.com/Microsoft/vcpkg/issues

由于我们需要使用https,并且使用openssl库,所以应该安装curl[openssl]. 

接下来要确定编译的模式,包括架构、32位还是64位、静态链接还是动态链接、release还是debug。这些信息属于vcpkg的triplets。那么vcpkg支持哪些triplets呢?

Triplets的介绍参考微软官网:https://learn.microsoft.com/en-us/vcpkg/concepts/triplets

运行vcpkg help triplet查看环境支持的triplets:

e:\vcpkg\vcpkg-master>vcpkg help triplet
Built-in Triplets:
  arm-neon-android
  arm64-android
  arm64-osx
  arm64-uwp
  arm64-windows
  x64-android
  x64-linux
  x64-osx
  x64-uwp
  x64-windows-static
  x64-windows
  x86-windows
Community Triplets:
  arm-android
  arm-ios
  arm-linux-release
  arm-linux
  arm-mingw-dynamic
  arm-mingw-static
  arm-uwp-static-md
  arm-uwp
  arm-windows-static
  arm-windows
  arm64-ios-release
  arm64-ios-simulator-release
  arm64-ios-simulator
  arm64-ios
  arm64-linux-release
  arm64-linux
  arm64-mingw-dynamic
  arm64-mingw-static
  arm64-osx-dynamic
  arm64-osx-release
  arm64-uwp-static-md
  arm64-windows-static-md
  arm64-windows-static-release
  arm64-windows-static
  arm64ec-windows
  armv6-android
  loongarch32-linux-release
  loongarch32-linux
  loongarch64-linux-release
  loongarch64-linux
  mips64-linux
  ppc64le-linux-release
  ppc64le-linux
  riscv32-linux-release
  riscv32-linux
  riscv64-linux-release
  riscv64-linux
  s390x-linux-release
  s390x-linux
  wasm32-emscripten
  x64-freebsd
  x64-ios
  x64-linux-dynamic
  x64-linux-release
  x64-mingw-dynamic
  x64-mingw-static
  x64-openbsd
  x64-osx-dynamic
  x64-osx-release
  x64-uwp-static-md
  x64-windows-release
  x64-windows-static-md-release
  x64-windows-static-md
  x64-windows-static-release
  x64-xbox-scarlett-static
  x64-xbox-scarlett
  x64-xbox-xboxone-static
  x64-xbox-xboxone
  x86-android
  x86-freebsd
  x86-ios
  x86-linux
  x86-mingw-dynamic
  x86-mingw-static
  x86-uwp-static-md
  x86-uwp
  x86-windows-static-md
  x86-windows-static
  x86-windows-v120

 这些triplet是什么意思呢?在triplets文件夹中有所有列出来的triplet,随便找一个看看,例如:community/x64-windows-static-md-release.cmake。

set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)

set(VCPKG_BUILD_TYPE release)

 VCPKG_TARGET_ARCHITECTURE:这个不用解释。

VCPKG_CRT_LINKAGE:使用哪个运行库,对应vs选项MT、MTD、MD、MDD

VCPKG_LIBRARY_LINKAGE:生成动态库还是静态库

VCPKG_BUILD_TYPE:编译release还是debug。

Todo:我还有一个疑问,用哪个c++标准编译的?我安装的使用vs2019。

5. 编译静态连接的静态库

vcpkg install curl[openssl]:x86-windows-static-release

vcpkg在安装 过程中,会检查依赖的包,并自动下载,放在tools目录中。确实非常方便。

不过在我的使用场景中,有个问题,就是openssl的版本。我发现vcpkg自动下载的openssl是3.2.1版本。但是我其他项目使用的是1.1.1j版本,会不会冲突?如何避免冲突?这其实是包管理中非常重要的问题。为了方便,我都采用3.2.1版本的openssl。

编译完成之后,再installed/x64-windows-static-release目录中可以看到编译好的库。

https demo

库已经编译好,编一个demo试试。从网站上下载了一个demo:https://curl.se/libcurl/c/https.html,把网址修改为:https://www.baidu.com,并且不验证对方。编译时指定库的头文件目录和库目录,并连接库即可。我这里是把libs目录copy到工程的../../目录。

#添加库的头文件目录
include_directories(../../libs/include)

#添加库目录
link_directories(${PROJECT_SOURCE_DIR}/../../libs/lib)

#链接库
target_link_libraries(${PROJECT_NAME} WS2_32.LIB CRYPT32.LIB libcrypto libssl libcurl.lib zlib.lib)

 编译,执行成功。

完整的demo代码如下:

#include <stdio.h>
#include <curl/curl.h>
 
int main(void)
{
  CURL *curl;
  CURLcode res;
 
  curl_global_init(CURL_GLOBAL_DEFAULT);
 
  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "https://www.baidu.com");
 

#define SKIP_PEER_VERIFICATION
#ifdef SKIP_PEER_VERIFICATION
    /*
     * If you want to connect to a site who is not using a certificate that is
     * signed by one of the certs in the CA bundle you have, you can skip the
     * verification of the server's certificate. This makes the connection
     * A LOT LESS SECURE.
     *
     * If you have a CA cert for the server stored someplace else than in the
     * default bundle, then the CURLOPT_CAPATH option might come handy for
     * you.
     */
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
 
#define SKIP_HOSTNAME_VERIFICATION
#ifdef SKIP_HOSTNAME_VERIFICATION
    /*
     * If the site you are connecting to uses a different host name that what
     * they have mentioned in their server certificate's commonName (or
     * subjectAltName) fields, libcurl refuses to connect. You can skip this
     * check, but it makes the connection insecure.
     */
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
 
    /* cache the CA cert bundle in memory for a week */
    curl_easy_setopt(curl, CURLOPT_CA_CACHE_TIMEOUT, 604800L);
 
    /* Perform the request, res gets the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
 
    /* always cleanup */
    curl_easy_cleanup(curl);
  }
 
  curl_global_cleanup();
 
  return 0;
}

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐