VS2010编译libcurl库并简单使用(c语言)

news2025/1/21 1:02:44

libcurl是什么?

       libcurl主要功能就是用不同的协议连接和沟通不同的服务器~也就是相当封装了的sockPHP 支持libcurl(允许你用不同的协议连接和沟通不同的服务器)。 libcurl当前支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传(当然你也可以使用PHP的ftp扩展), HTTP基本表单上传,代理,cookies,和用户认证。

一、编译

libcurl使用前需要根据自己的代码编辑器情况进行编译,否则会出现各种各样不适配的问题。

1)到官网下载压缩包(自行选择合适的版本)

网址:( curl - Download )

2)解压压缩包,进入加压后的文件夹,运行buildconf.bat

这一步是为了后续编译作预备工作。注意:错过该步骤,后续编译可能会有异常。

3)在开始菜单栏,找到VS2010,以管理员身份运行x64本机工具命令提示。

4)切换到你的curl库的winbuild 文件夹下

cd C:\Users\xijin001\Desktop\libcrul\curl-8.0.1\winbuild 

5)根据将要在哪个VS版本下使用,输入对应的编译命令,开始编译,等待编译完成。

下述是编译VS2010版本下使用的64位release的静态库的编译命令

nmake /f Makefile.vc mode=static VC=10 MACHINE=x64 DEBUG=no

若要编译32位,将x64改为x86;若要编译debug版本,将no改为yes;若编译动态库,将static改为dll;若为其他版本的VS,将10改为你VS版本对应的VC版本值。

vs发布版本与vc版本的对应关系

VS发布包版本

vc版本

Visual Studio 6

VC6

Visual Studio 2003

VC7

Visual Studio 2005

VC8

Visual Studio 2008

VC9

Visual Studio 2010

VC10

Visual Studio 2012

VC11

Visual Studio 2013

VC12

Visual Studio 2015

VC14

Visual Studio 2017

VC15

Visual Studio 2019

VC16

Visual Studio 2022

VC17

成功编译完成的界面

6)至此,库已经编译完成。

编译后的文件会在builds文件夹下

二、配置

1)在vs2010下新建一个控制台项目

可以参考下述链接中的第二部分【二、使用Visual Studio 2010编写C语言 Hello World 程序】内容

VS2022 和 VS2010 C语言控制台输出 Hello World_vs控制台输出_西晋的no1的博客-CSDN博客

2)将【一、编译】生成的库复制到此项目demo.cpp所在的文件夹中,如下图:

如果是项目工程有多个其它库包含的话,最好把这两个目录重命名一下,例如改成Curl_inc和Curl_lib(后面配置需要跟着改)

3)选择项目名,点击鼠标右键,选择弹出菜单中的属性,进入项目属性页

4)在项目属性页选择与【一、编译】生成的库对应的配置和平台

配置选择Release,平台选择x64,这里的选择是因为【一、编译】编译库时的配置参数是Release,x64,如要debug或x86,请根据【一、编译】重新编译,这里选择对应配置。

5)在项目属性页的配置属性->VC++目录下分别设置包含目录和库目录

包含目录添加:

$(ProjectDir)\include;

库目录添加:

$(ProjectDir)\lib;

$(ProjectDir)是项目目录的变量,这样即使移动工程到不同文件夹也不会受影响

6)添加预处理器定义

项目属性页的配置属性->C/C++->预处理器->预处理器定义:添加:

CURL_STATICLIB

本项目是静态编译,所以需要将CURL_STATICLIB添加至工程。

7)添加其它需要的库

项目属性页的配置属性->链接器->输入->附加依赖项:

libcurl_a.lib;Ws2_32.lib;Wldap32.lib;winmm.lib;Crypt32.lib;Normaliz.lib;

8)C++运行库一般选择/MD。

项目属性页的配置属性->C/C++->代码生成->运行库

至此,完成配置。

注意最后要点击确定,使得上述配置生效。

三、验证上述编译和配置操作成功与否

下面使用一个简单的示例,验证上述【一、编译】和【二、配置】操作是否成功。

将下述代码放到demo.cpp文件中,编译运行,能成功运行并获取到数据,则表明上述【一、编译】和【二、配置】操作成功。

#include <curl/curl.h>

int main() {
    CURL* curl = curl_easy_init();
    if (curl) {
        CURLcode res;
        curl_easy_setopt(curl, CURLOPT_URL, "https://www.baidu.com");
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }
    return 0;
}

运行截图:

上图中乱码是因为没有对中文进行处理。

处理中文乱码问题,参考链接: https://blog.csdn.net/xijinno1/article/details/130050416

四、更多使用实例

1)最简单的用libcurl库获取网页源码并保存到文件

#include "curl/curl.h"

// 这是libcurl接收数据的回调函数,相当于recv的死循环
// 其中stream可以自定义数据类型,这里我传入的是文件保存路径
static size_t write_callback( void *ptr, size_t size, size_t nmemb, void *stream )
{
    int len = size * nmemb;
    int written = len;
    FILE *fp = NULL;

    fp = fopen( (char*) stream, "wb" );

    if (fp)
    {
        fwrite( ptr, size, nmemb, fp );
    }
    return written;
}

int GetUrl( const char *url, char *savepath )
{
    CURL *curl;
    CURLcode res;
    struct curl_slist *chunk = NULL;

    curl = curl_easy_init();
    if ( curl ) {
        curl_easy_setopt( curl, CURLOPT_VERBOSE, 0L );
        curl_easy_setopt( curl, CURLOPT_URL, url );
        //指定回调函数
        curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_callback);
        //这个变量可作为接收或传递数据的作用
        curl_easy_setopt( curl, CURLOPT_WRITEDATA, savepath );
        res = curl_easy_perform( curl );
        if (res == CURLE_OK)
        {
            return 1;
        }
    }
    return 0;
}

int main( void )
{
    if ( GetUrl( "www.baidu.com", "1.txt" ) )
    {
        printf( "OK\n" );
    }
    return 0;
}

2)获取网页源码并保存变量中,输出到控制台

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
 
#include <curl/curl.h>
 
struct MemoryStruct {
  char *memory;
  size_t size;
};
 
static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;
 
// 注意这里根据每次被调用获得的数据重新动态分配缓存区的大小
  char *ptr = (char *)realloc(mem->memory, mem->size + realsize + 1);
  if(!ptr) {
    /* out of memory! */
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }
 
  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
 
  return realsize;
}
 
int main(void)
{
  SetConsoleOutputCP(CP_UTF8);
  CURL *curl_handle;
  CURLcode res;
 
  struct MemoryStruct chunk;
 
  chunk.memory = (char*)malloc(sizeof(char));  /* will be grown as needed by the realloc above */
  chunk.size = 0;    /* no data at this point */
 
  curl_global_init(CURL_GLOBAL_ALL);
 
  /* init the curl session */
  curl_handle = curl_easy_init();
 
  /* specify URL to get */
  curl_easy_setopt(curl_handle, CURLOPT_URL, "https://www.baidu.com");
 
  /* send all data to this function  */
 // 对于同一次阻塞的curl_easy_perform而言,在写完获取的数据之前,会多次调用 WriteMemoryCallback
  curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
 
  /* we pass our 'chunk' struct to the callback function */
  curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
 
  /* some servers do not like requests that are made without a user-agent
     field, so we provide one */
  curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
 
  /* get it! */
// 对于同一次阻塞的curl_easy_perform而言,在写完获取的数据之前,会多次调用 WriteMemoryCallback
  res = curl_easy_perform(curl_handle);
 
  /* check for errors */
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
  }
  else {
    /*
     * Now, our chunk.memory points to a memory block that is chunk.size
     * bytes big and contains the remote file.
     *
     * Do something nice with it!
     */
 
    printf("%lu bytes retrieved\n", (unsigned long)chunk.size);
    printf("%s", (unsigned long)chunk.memory);
  }
 
  /* cleanup curl stuff */
  curl_easy_cleanup(curl_handle);
 
  free(chunk.memory);
 
  /* we are done with libcurl, so clean it up */
  curl_global_cleanup();
 
  return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/414458.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring 之依赖注入底层原理

Spring 框架作为 Java 开发中最流行的框架之一&#xff0c;其核心特性之一就是依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;。在Spring中&#xff0c;依赖注入是通过 IOC 容器&#xff08;Inversion of Control&#xff0c;控制反转&#xff09;来实现…

助力研发效能变革,第七届Techo TVP 开发者峰会圆满落下帷幕

引言 在互联网数字企业结束“野蛮扩张”、追求高质量增长的今天&#xff0c;研发效能已然成为企业关注的核心命题。伴随着云原生概念在软件领域的落地生根&#xff0c;云原生正驱动软件应用设计、实现、部署及运维方式的巨变&#xff0c;为研发效能治理带来了新的挑战与机遇&am…

2022国赛31:虚拟化-------安装docker

大赛试题内容: 八、虚拟化(20) 在Windows3安装docker,导入NanoServer镜像。软件包和镜像存放在物理机D:\soft\DockerWindows。创建名称为web的容器,映射虚拟机的80端口到容器的80端口,容器启动后运行cmd命令,保持容器处于运行状态。解答过程: windows docker 安装 1.添…

知识图谱嵌入方法-transE

目录 一、知识图谱嵌入 二、transE算法 三、缺点 一、知识图谱嵌入 知识图谱(Knowledge Graph&#xff0c;KG) 是大规模语义网络知识库&#xff0c;利用三元组&#xff08;实体&#xff0c;关系&#xff0c;实体&#xff09;来描述具体的知识&#xff0c;其具有语义丰富、结…

vue-element-admin 动态菜单改造

vue-element-admin 动态菜单改造 vue-element-admin 是一款优秀后台前端解决方案&#xff0c;它基于 vue 和 element-ui实现。开源后台管理系统解决方案项目 Boot-admin的前端模块就是基于vue-element-admin开发而来。 作为一款纯前端的后台界面解决方案&#xff0c;vue-elem…

剑指 Offer 51. 数组中的逆序对

剑指 Offer 51. 数组中的逆序对 难度&#xff1a;hard\color{red}{hard}hard 题目描述 在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组&#xff0c;求出这个数组中的逆序对的总数。 示例 1: 输入: [7…

怎么设计秒杀系统?

秒杀系统需要考虑哪些要素&#xff1f; 要能支持高并发用户体验要好&#xff0c;不要返回异常信息对系统要友好&#xff08;针对秒杀可以做业务上的隔离&#xff0c;单独把秒杀系统部署到独立的集群服务器上&#xff1b;可动态配置业务参数&#xff0c;比如商品金额&#xff0…

电磁兼容(EMC)的标准与测试内容

在国际范围上&#xff0c;电磁兼容标准的制定已经有了70多年的发展历程&#xff0c;最早为了保护无线电通信和广播&#xff0c;国际无线电干扰特别委员会&#xff08;CISPR&#xff09;对各种用电设备和系统提出了相关的电磁干扰发射限值和测量方法。到了20世纪60&#xff5e;7…

机器学习:基于朴素贝叶斯(Naive Bayes)的分类预测

目录 一、简介和环境准备 简介&#xff1a; 环境&#xff1a; 二、实战演练 2.1使用葡萄&#xff08;Wine&#xff09;数据集&#xff0c;进行贝叶斯分类 1.数据导入 2.模型训练 3.模型预测 2.2模拟离散数据集–贝叶斯分类 1.数据导入、分析 2.模型训练、预测 三、原…

TiDB进阶篇-TiDB Server架构

简介 较深入的介绍TiDB Server。 TiDB Server 架构 图解 1.下面是负责SQL语句的解析和优化。 2.下面试负责TiKV存储多版本&#xff0c;过期版本的清理作用。 3.复杂SQL的拆分&#xff08;如果是点查那么就不需要经过DistSQL&#xff09;。 4.事务相关。 5.负责PD和TiKV的通信…

js 事件流程

描述 JavaScript 的执行是单线程的&#xff0c;后面的任务需要等待前面的任务完全完成后&#xff0c;再去执行。DOM 事件&#xff08;文件的加载等&#xff09;、定时器、网络请求等事件&#xff0c;并不会消耗 CPU&#xff0c;这些事件无需等候&#xff0c;所以出现了异步。主…

Java后端新人入职第一天,环境搭建,全看这篇就行了

本文主要是记录一下一个新人java后端开发来到一个新公司,如何快速将自己的相关开发环境搭建好,包括Java、Maven、Tomcat、idea、Redis、Mysql等等,有的公司会有相关版本的要求,不过安装配置步骤基本一样的,我这里就以目前比较流行的版本进行详细说明。 一:基础环境搭建:…

Arduino开发之如何连接GPS模块?

文章目录0、引言1、GPS模块说明2、接调试助手测试GPS模块接收数据3、代码编写4、功能演示0、引言 NEO-6M/7M GPS模块&#xff0c;具有高灵敏度、低功耗、小型化、高追踪灵敏度&#xff0c;大大扩大了其定位的覆盖面&#xff0c;在普通GPS接收模块不能定位的地方&#xff0c;如狭…

编译原理考试大题分析【太原理工大学】

有些基本公式可以看这里&#xff0c;大题内容请以本篇为准&#xff01;https://blog.csdn.net/m0_52861684/article/details/130071191?spm1001.2014.3001.5501 之前说错了&#xff0c;考试题型没有简答题和填空题&#xff0c;只有十个选择题是 20 分&#xff0c;其余全是大题…

ESP32设备驱动-VEML6075紫外线(UV)光传感器驱动

VEML6075紫外线(UV)光传感器驱动 文章目录 VEML6075紫外线(UV)光传感器驱动1、VEML6075介绍2、硬件准备3、软件准备4、驱动实现1、VEML6075介绍 VEML6075 可感应 UVA 和 UVB 光,并使用 CMOS 工艺将光电二极管、放大器和模拟/数字电路集成到单个芯片中。 应用 UV 传感器时,它…

ChatGPT和GPT-4带你选笔记本电脑

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

最近ChatGPT封号太严重了,这里是解封攻略步骤(建议收藏)

这个周末&#xff0c;先是意大利暂时封杀ChatGPT&#xff0c;限制OpenAI处理本国用户信息。 接着&#xff0c;据韩国媒体报道&#xff0c;三星导入ChatGPT不到20天&#xff0c;便曝出机密资料外泄。 还没结束&#xff0c;又有大量网友发现ChatGPT目前停止注册&#xff0c;开始…

【vue】vue中下载文件的方法

文章目录1. 下载后端返回文件1.1 后端为post请求返回二进制流文件URL.createObjectURLFileReader1.2 后端直接返回get请求文件2. 下载本地文件1. 下载后端返回文件 1.1 后端为post请求返回二进制流文件 Blob Blob对象标识一个不可变、原始数据的类文件对象。Blob表示的不一定…

RabbitMQ( 发布订阅模式 ==> FanoutExchange )

本章目录&#xff1a; 何为发布订阅模式FanoutExchange具体使用一、何为发布订阅模式 在上一篇文章中&#xff0c;我们创建了Work Queue并且发送任务&#xff0c;在Work Queue中&#xff0c;每个任务只会被一个消费者消费&#xff0c;任务消费后就被清除了。 而在本篇中&…

0202心跳和服务续约源码解析-nacos2.x-微服务架构

文章目录1 客户端心跳任务2 服务端处理2.1 服务注册时开启客户端心跳检查2.2 客户端发送心跳任务续约2.3 服务实例移除2.4 心跳任务闭环结语1 客户端心跳任务 在上一篇文章0201服务注册源码解析-nacos2.x-微服务架构分析客户端服务注册的时候&#xff0c;流程在NacosNamingSer…