万捷博客

万捷博客
一个知识汇聚的地方
首页 » c++ » c++使用CURL实现POST网页访问windows版

c++使用CURL实现POST网页访问windows版

测试环境:

操作系统:windows 10

工具:vs2019

测试库版本:curl-7.68.0

CURL编译方法:

libcurl库下载地址:https://curl.haxx.se/download.html

我下载的是curl-7.68.0.zip

1.jpg

解压文件后,进入目录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就可以了。

文章如无特别注明均为原创! 作者: admin, 转载或复制请以 超链接形式 并注明出处 万捷博客
原文地址《 c++使用CURL实现POST网页访问windows版》发布于2020-2-3

打赏作者
提示信息

SQL语句执行错误:SELECT gid,title FROM emlog_blog WHERE hide='n' AND type='blog' AND gid!=H AND sortid=H ORDER BY rand() LIMIT 0,6
Unknown column 'H' in 'where clause'

«点击返回