我已经在Windows上使用Visual C ++编译器将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;
};
}
实施(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_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/");
用于编译第二个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;
但是,我目前对到底是什么问题一无所知。相同的代码可以在Clang上针对Android和iOS很好地编译。
有人看到要使用Visual C ++进行编译需要做什么吗?
如前所述,SOCKET
是Windows定义的。更具体地说,它在中定义WinSock2.h
。我包括了那个特定的标题,但没有解决问题。但是,第二个dll使用了预编译的头文件(pch.h
)。WinSock2.h
将pch.h
文件包含在文件中后,编译器错误最终得到解决。
但是,要为Windows UWP应用程序构建libcurl,还需要完成另一个关键步骤。WinSock2.h
在pch.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对这个库的描述如下:
为方便起见,Microsoft Windows软件开发工具包(SDK)中提供了一个名为OneCore.lib的伞形库,该库提供了所有Windows 10设备通用的Win32 API子集的导出。将您的经典台式机应用程序或驱动程序与OneCore.lib(无其他库)链接,以访问这些API。如果将应用程序或驱动程序链接到OneCore.lib,并且仅在该库中调用Win32 API,则您的应用程序或驱动程序将在所有Windows 10设备上成功加载。
有关更多信息,请参见此链接OneCore.lib
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句