gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:08 27 4
gpt4 key购买 nike

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

header (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;
};
}

实现(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;
}

该测试程序编译得很好。

(顺便说一句:我知道 curl_global_initcurl_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/");

用于编译第二个 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>

但是,尝试编译第二个 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'

在第一条错误消息之后,我找到了 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 */

因此编译器基本上会提示以下行:

134:  typedef SOCKET curl_socket_t;

但是,我目前对问题的确切原因一无所知。对于 Android 和 iOS,相同的代码可以通过 Clang 正常编译。

有人知道要用 Visual C++ 进行编译需要做什么吗?

最佳答案

如前所述,SOCKET 是由 Windows 定义的。更具体地说,它在 WinSock2.h 中定义。我包含了那个特定的标题,但没有解决问题。但是,第二个 dll 使用预编译的头文件 (pch.h)。一旦我将 WinSock2.h 包含在 pch.h 文件中,编译器错误终于得到解决。

但是,要为 Windows UWP 应用程序构建 libcurl,还需要完成另一个关键步骤。在 pch.h 文件中包含 WinSock2.h 只能解决编译器错误,但会导致两个链接器错误,如下所示:

error LNK2019: unresolved external symbol __imp_VerSetConditionMask referenced in function Curl_verify_windows_version
error LNK2019: unresolved external symbol __imp_VerifyVersionInfoA referenced in function Curl_verify_windows_version
fatal error LNK1120: 2 unresolved externals

这些术语可以通过指示链接器包含附加库 OneCore.lib 来解决。 Microsoft 对此库的描述如下:

For convenience, an umbrella library named OneCore.lib is provided in the Microsoft Windows Software Development Kit (SDK), which provides the exports for the subset of Win32 APIs that are common to all Windows 10 devices. Link your classic desktop app or driver with OneCore.lib (and no other libraries) to access these APIs. If you link your app or driver to OneCore.lib, and you only call Win32 APIs in that library, then your app or driver will load successfully on all Windows 10 devices.

查看此 link有关 OneCore.lib 的更多详细信息。

关于c++ - 在 C++ 程序中使用 libcurl 会导致 Visual C++ 编译器发出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56557115/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com