在 C++ 程序中使用 libcurl 会导致 Visual C++ 编译器发出错误

ack*_*ckh 5 c++ curl libcurl visual-c++

我已经使用 Visual C++ 编译器在 Windows 上将 libcurl 编译成一个 dll。除了编译后的 libcurl 源代码外,该 dll 还包含一个简单的测试程序,如下所示:

标题 ( HttpClient.h):

#pragma once

#include <string>

#include "curl/curl.h"


namespace My::Project
{
  class HttpClient
  {
  public:
    HttpClient();
    ~HttpClient();
    std::string Get(std::string address);

  private:
    CURL* easy_handle;
  };
}
Run Code Online (Sandbox Code Playgroud)

实施(HttpClient.cpp):

#include "HttpClient.h"

#include <iostream>

using namespace My::Project


HttpClient::HttpClient()
{
  easy_handle = curl_easy_init();
  curl_global_init(CURL_GLOBAL_ALL);
}


HttpClient::~HttpClient()
{
  curl_global_cleanup();
}


static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
  ((std::string*)userp)->append((char*)contents, size * nmemb);
  return size * nmemb;
}


std::string HttpClient::Get(std::string address)
{
  std::string html;

  curl_easy_setopt(easy_handle, CURLOPT_URL, address.c_str());
  curl_easy_setopt(easy_handle, CURLOPT_FOLLOWLOCATION, 1L);
  curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, WriteCallback);
  curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &html);
  CURLcode returnValue = curl_easy_perform(easy_handle);

  if(returnValue != CURLE_OK)
  {
    html = "Failed to retrieve HTML";
  }

  curl_easy_cleanup(easy_handle);
  return html;
}
Run Code Online (Sandbox Code Playgroud)

该测试程序编译得很好。

(顺便说一句:我知道curl_global_init并且curl_global_cleanup只能调用一次。这只是一个测试程序......)

现在,我想在另一个 dll 中引用该 dll 并创建HttpClient该类的实例并按如下方式使用它:

#include "<relative-path>/HttpClient.h" 

using namespace My::Project;

// Within a constructor of another class
HttpClient client;
std::string html = client.Get("https://www.google.com/");
Run Code Online (Sandbox Code Playgroud)

用于编译第二个 dll 的编译器调用如下所示:

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\HostX86\x64\CL.exe
/c
/I<project path>
/I"Generated Files\\"
/Iobj\Debug\x64\
/I<path to curl source>\curl\include
/ZI
/JMC
/ZW
/ZW:nostdlib
/nologo
/W3
/WX-
/diagnostics:column
/sdl
/MP
/Od
/Oy-
/D _WINRT_DLL
/D _WINDLL
/D _UNICODE
/D UNICODE
/D _DEBUG
/D WINAPI_FAMILY=WINAPI_FAMILY_APP
/D __WRL_NO_DEFAULT_LIB__
/Gm-
/EHsc
/RTC1
/MDd
/GS
/fp:precise
/Zc:wchar_t
/Zc:forScope
/Zc:inline
/std:c++17
/Yu"pch.h"
/Fp"obj\Debug\x64\pch.pch"
/Fo"obj\Debug\x64\\"
/Fd"obj\Debug\x64\vc142.pdb"
/Gd
/TP
/wd28204
/FU"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\lib\x86\store\references\platform.winmd"
/FU"<other winmd files>
/analyze-
/FC
/errorReport:prompt
/bigobj
<path to cpp file invoking HttpClient>
Run Code Online (Sandbox Code Playgroud)

但是,尝试编译第二个 dll 会导致 Visual C++ 编译器发出以下错误:

<path to curl source>\curl\include\curl\curl.h(134,29): error C4430:  missing type specifier - int assumed. Note: C++ does not support default-int
<path to curl source>\curl\include\curl\curl.h(134,16): error C2146:  syntax error: missing ';' before identifier 'curl_socket_t'
<path to curl source>\curl\include\curl\curl.h(397,52): error C2061:  syntax error: identifier 'curl_socket_t'
<path to curl source>\curl\include\curl\curl.h(407,23): error C2079:  'curl_sockaddr::addr' uses undefined struct 'sockaddr'
<path to curl source>\curl\include\curl\curl.h(411,3): error C2065:  'curl_opensocket_callback': undeclared identifier
<path to curl source>\curl\include\curl\curl.h(411,27): error C4430:  missing type specifier - int assumed. Note: C++ does not support default-int
<path to curl source>\curl\include\curl\curl.h(411,27): error C2378:  'curl_socket_t': redefinition; symbol cannot be overloaded with a typedef
<path to curl source>\curl\include\curl\curl.h(134): message :  see declaration of 'curl_socket_t'
<path to curl source>\curl\include\curl\curl.h(411,28): error C2513:  'int': no variable declared before '='
<path to curl source>\curl\include\curl\curl.h(411,28): error C2143:  syntax error: missing ';' before '('
<path to curl source>\curl\include\curl\curl.h(411,34): error C2062:  type 'void' unexpected
<path to curl source>\curl\include\curl\curl.h(416,59): error C2061:  syntax error: identifier 'curl_socket_t'
<path to curl source>\curl\include\curl\multi.h(113,19): error C3646:  'fd': unknown override specifier
<path to curl source>\curl\include\curl\multi.h(113,19): error C4430:  missing type specifier - int assumed. Note: C++ does not support default-int
<path to curl source>\curl\include\curl\multi.h(157,47): error C2061:  syntax error: identifier 'fd_set'
<path to curl source>\curl\include\curl\multi.h(271,51): error C2061:  syntax error: identifier 'curl_socket_t'
<path to curl source>\curl\include\curl\multi.h(292,76): error C2061:  syntax error: identifier 'curl_socket_t'
<path to curl source>\curl\include\curl\multi.h(296,62): error C2061:  syntax error: identifier 'curl_socket_t'
<path to curl source>\curl\include\curl\multi.h(410,55): error C2061:  syntax error: identifier 'curl_socket_t'
Run Code Online (Sandbox Code Playgroud)

跟进第一条错误消息将我带到以下代码片段curl.h

131:  #ifndef curl_socket_typedef
132:  /* socket typedef */
133:  #if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
134:  typedef SOCKET curl_socket_t;
135:  #define CURL_SOCKET_BAD INVALID_SOCKET
136:  #else
137:  typedef int curl_socket_t;
138:  #define CURL_SOCKET_BAD -1
139:  #endif
140:  #define curl_socket_typedef
141:  #endif /* curl_socket_typedef */
Run Code Online (Sandbox Code Playgroud)

所以编译器基本上抱怨以下行:

134:  typedef SOCKET curl_socket_t;
Run Code Online (Sandbox Code Playgroud)

但是,我目前对问题究竟是什么一无所知。相同的代码在 Android 和 iOS 上用 Clang 编译得很好。

有没有人看到需要做什么才能使用 Visual C++ 进行编译?