测试环境:
操作系统:windows 10
工具:vs2019
测试库版本:curl-7.68.0
CURL编译方法:
libcurl库下载地址:https://curl.haxx.se/download.html
我下载的是curl-7.68.0.zip
解压文件后,进入目录curl-7.68.0\projects\Windows\VC15\
使用VS运行curl-all.sln,选择LIB Release,生成即可,生成完毕后在curl-7.68.0\build\Win32\VC15\LIB Release目录会出现libcurl.lib
至此编译完毕。
VS配置:
加入预编译选项,项目》右键 属性》C/C++》预处理器》预处理器定义》增加一行CURL_STATICLIB;HTTP_ONLY
链接器加入LIB库,将libcurl.lib复制到项目目录中,项目》右键 属性》链接器》附加库目录,将libcurl.dll的目录增加到列表中
加入文件头,将curl-7.68.0\include中的curl目录复制到项目目录中,然后 头文件》添加》现有项目》选择curl目录中的curl.h,加入头文件
使用方法:
//文件名 test.cpp
#include <stdio.h>
#include "curl/curl.h"
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "wldap32.lib")
#pragma comment(lib, "libcurl.lib")
int main()
{
curl_global_init(CURL_GLOBAL_ALL);
CURL* curl = curl_easy_init();
if (curl)
{
const char* url = "http://www.baidu.com/";
curl_easy_setopt(curl, CURLOPT_URL, url);
//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");//POST数据
CURLcode curlCode = curl_easy_perform(curl);
if (CURLE_OK != curlCode) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(curlCode));
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
system("pause");
return 0;
}
示例2:
//文件名 test.cpp
#include <stdio.h>
#include "curl/curl.h"
#include <string.h>
#include <sstream>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "wldap32.lib")
#pragma comment(lib, "libcurl.lib")
size_t write_data(void* buffer, size_t size, size_t nmemb, void* userp)
{
//将void* 指针转换成char* 指针, 并且读取对应长度
std::string data((char*)buffer, size * nmemb);
//输出到开发者设置的数据类型中, 这里是stringstream
*((std::stringstream*) userp) << data << std::endl;
//Data = (char*)realloc(Data, datasize + size * nmemb + 1);//根据数据大小扩充指针的内存
//memcpy(Data+ datasize, buffer, size * nmemb);//将数据拷贝到数据的尾部
//datasize += size * nmemb;//更新数据长度
//return datasize;// size* nmemb;
return size * nmemb;
}
std::string network(const std::string& url)
{
//创建一个easy_handle, 不要在线程直接共享easy_handle
CURL* easy_handle = curl_easy_init();
//数据输出存储的对象
std::stringstream out;
//检查是否创建成功
if (easy_handle == NULL)
{
//抛出错误异常
throw std::runtime_error("create easy_handle fail");
}
curl_easy_setopt(easy_handle, CURLOPT_URL, url.c_str());
//设置请求方式为POST,不添加这一句默认是GET
//curl_easy_setopt(easy_handle, CURLOPT_POST, 1);
//当请求方式为POST时,设置提交的数据
//curl_easy_setopt(easy_handle, CURLOPT_POSTFIELDS, data);
//如果不提供这样的回调函数,那个curl只是简单的把数据输出到标准输出流中
curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, &write_data);
//绑定数据输出
curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &out);
//开始进行请求
curl_easy_perform(easy_handle);
//清理curl_easy
curl_easy_cleanup(easy_handle);
return out.str();
}
int main()
{
std::string a = network("http://42.51.39.198:86/");
MessageBoxA(0, a.c_str(), 0, NULL);
return 0;
}
常见错误:
1、 枚举类型“CURLcode”未设定范围。相比于 "enum",首选 "enum class" (Enum.3)。
无法解析的外部符号 __imp__closesocket@4,该符号在函数 _Curl_multi_handle 中被引用
无法解析的外部符号 __imp__curl_global_init,该符号在函数 _main 中被引用
解决办法,没有引用依赖的库:
1、在头文件下面加入引用
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "wldap32.lib")
2、加入预编译选项,项目》右键 属性》C/C++》预处理器》预处理器定义》增加一行CURL_STATICLIB
1. 遇到如下问题
1>libcurl.lib(easy.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAStartup
1>libcurl.lib(telnet.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAStartup
1>libcurl.lib(easy.obj) : error LNK2001: 无法解析的外部符号 __imp_WSACleanup
1>libcurl.lib(telnet.obj) : error LNK2001: 无法解析的外部符号 __imp_WSACleanup
1>libcurl.lib(ftp.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAGetLastError
1>libcurl.lib(telnet.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAGetLastError
1>libcurl.lib(tftp.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAGetLastError
1>libcurl.lib(asyn-thread.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAGetLastError
1>libcurl.lib(select.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAGetLastError
1>libcurl.lib(sendf.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAGetLastError
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAGetLastError
1>libcurl.lib(select.obj) : error LNK2001: 无法解析的外部符号 __WSAFDIsSet
1>libcurl.lib(select.obj) : error LNK2001: 无法解析的外部符号 __imp_select
1>libcurl.lib(select.obj) : error LNK2001: 无法解析的外部符号 __imp_WSASetLastError
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_WSASetLastError
1>libcurl.lib(curl_addrinfo.obj) : error LNK2001: 无法解析的外部符号 __imp_WSASetLastError
1>libcurl.lib(sendf.obj) : error LNK2001: 无法解析的外部符号 __imp_recv
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_recv
1>libcurl.lib(sendf.obj) : error LNK2001: 无法解析的外部符号 __imp_send
1>libcurl.lib(telnet.obj) : error LNK2001: 无法解析的外部符号 __imp_send
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_bind
1>libcurl.lib(ftp.obj) : error LNK2001: 无法解析的外部符号 __imp_bind
1>libcurl.lib(tftp.obj) : error LNK2001: 无法解析的外部符号 __imp_bind
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_closesocket
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_connect
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_getpeername
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_getsockname
1>libcurl.lib(ftp.obj) : error LNK2001: 无法解析的外部符号 __imp_getsockname
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_getsockopt
1>libcurl.lib(smb.obj) : error LNK2001: 无法解析的外部符号 __imp_htons
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_htons
1>libcurl.lib(curl_addrinfo.obj) : error LNK2001: 无法解析的外部符号 __imp_htons
1>libcurl.lib(ftp.obj) : error LNK2001: 无法解析的外部符号 __imp_htons
1>libcurl.lib(telnet.obj) : error LNK2001: 无法解析的外部符号 __imp_htons
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_ntohs
1>libcurl.lib(ftp.obj) : error LNK2001: 无法解析的外部符号 __imp_ntohs
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_setsockopt
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_socket
1>libcurl.lib(connect.obj) : error LNK2001: 无法解析的外部符号 __imp_WSAIoctl
1>libcurl.lib(curl_addrinfo.obj) : error LNK2001: 无法解析的外部符号 __imp_getaddrinfo
1>libcurl.lib(curl_addrinfo.obj) : error LNK2001: 无法解析的外部符号 __imp_freeaddrinfo
1>libcurl.lib(ftp.obj) : error LNK2001: 无法解析的外部符号 __imp_accept
1>libcurl.lib(ftp.obj) : error LNK2001: 无法解析的外部符号 __imp_listen
1>libcurl.lib(tftp.obj) : error LNK2001: 无法解析的外部符号 __imp_recvfrom
1>libcurl.lib(tftp.obj) : error LNK2001: 无法解析的外部符号 __imp_sendto
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_init
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_unbind_s
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_set_option
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_simple_bind_s
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_search_s
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_msgfree
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_err2string
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_first_entry
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_next_entry
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_first_attribute
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_next_attribute
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_get_values_len
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_value_free_len
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_get_dn
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ldap_memfree
1>libcurl.lib(ldap.obj) : error LNK2001: 无法解析的外部符号 __imp_ber_free
1>libcurl.lib(nonblock.obj) : error LNK2001: 无法解析的外部符号 __imp_ioctlsocket
具体步骤就是:
给工程添加依赖的库:项目->属性->链接器->输入->附加依赖项,把 ws2_32.lib、 winmm.lib、 wldap32.lib添加进去
注意,debug配置用libcurld.lib
2.如出现
error LNK2001: 无法解析的外部符号 __imp_curl_easy_perform
error LNK2001: 无法解析的外部符号 __imp_curl_easy_init
error LNK2001: 无法解析的外部符号 __imp_curl_slist_append
error LNK2001: 无法解析的外部符号 __imp_curl_slist_free_all
error LNK2001: 无法解析的外部符号 __imp_curl_easy_cleanup
error LNK2001: 无法解析的外部符号 __imp_curl_easy_setopt
加入预编译选项:项目->属性->c/c++ ->预处理器->预处理器,把 BUILDING_LIBCURL;HTTP_ONLY复制进去(注意不要丢了";")
3.如出现
1>libcurl.lib(cookie.obj) : error LNK2001: 无法解析的外部符号 __imp_fgets
1>libcurl.lib(netrc.obj) : error LNK2001: 无法解析的外部符号 __imp_fgets
1>libcurl.lib(mime.obj) : error LNK2001: 无法解析的外部符号 __imp_access
1>OLDNAMES.lib(access.obi) : error LNK2001: 无法解析的外部符号 __imp_access
1>libcurl.lib(tftp.obj) : error LNK2001: 无法解析的外部符号 __imp_strstr
1>libcurl.lib(digest.obj) : error LNK2001: 无法解析的外部符号 __imp_strstr
1>libcurl.lib(ftplistparser.obj) : error LNK2001: 无法解析的外部符号 __imp_strstr
1>libcurl.lib(url.obj) : error LNK2001: 无法解析的外部符号 __imp_strstr
1>libcurl.lib(http.obj) : error LNK2001: 无法解析的外部符号 __imp_strstr
1>libcurl.lib(transfer.obj) : error LNK2001: 无法解析的外部符号 __imp_strstr
1>libcurl.lib(ftp.obj) : error LNK2001: 无法解析的外部符号 __imp_strstr
1>libcurl.lib(warnless.obj) : error LNK2001: 无法解析的外部符号 __imp_read
1>OLDNAMES.lib(read.obi) : error LNK2001: 无法解析的外部符号 __imp_read
1>libcurl.lib(warnless.obj) : error LNK2001: 无法解析的外部符号 __imp_write
1>OLDNAMES.lib(write.obi) : error LNK2001: 无法解析的外部符号 __imp_write
1>libcurl.lib(parsedate.obj) : error LNK2001: 无法解析的外部符号 __imp__gmtime64
1>libcurl.lib(file.obj) : error LNK2001: 无法解析的外部符号 __imp_open
1>OLDNAMES.lib(open.obi) : error LNK2001: 无法解析的外部符号 __imp_open
1>libcurl.lib(smb.obj) : error LNK2001: 无法解析的外部符号 __imp__getpid
1>libcurl.lib(system_win32.obj) : error LNK2001: 无法解析的外部符号 __imp__mbspbrk
这个问题 :要 统一代码生成方式,如果是 Debug 就是多线程调试 /MTd,如果是 Release 就是多线程 /MT
C/C++ -> 代码生成 -> 运行库
curl 工程默认是MD ,改成MT就可以了。