- 编译
官方下载源码,找到winbuild目录。打开vs2013开发人员命令提示工具,编译debug版本:E:\cpp11\curl-7.51.0\winbuild>nmake /f Makefile.vc mode=static VC=12 DEBUG=yes
编译relase版本去掉DEBUG=yes就可以了;
builds目录下找到生成的include和lib目录; - 使用
附加头文件目录;
链接器加入lib库;
关键,关键,关键,C/C++预处理器中加入:BUILDING_LIBCURL - 上传文件例子
// ConsoleApplication7.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <curl/curl.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
CURL *curl;
CURLcode res;
struct stat file_info;
double speed_upload, total_time;
FILE *fd;
fopen_s(&fd, "hello", "rb");
//fd = fopen("debugit", "rb"); /* open file to upload */
if (!fd) {
return 1; /* can't continue */
}
/* to get the file size */
if (fstat(_fileno(fd), &file_info) != 0) {
return 1; /* can't continue */
}
curl = curl_easy_init();
if (curl) {
/* upload to this place */
curl_easy_setopt(curl, CURLOPT_URL,
"localhost:3000/hello");
/* tell it to "upload" to the URL */
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* set where to read from (on Windows you need to use READFUNCTION too) */
curl_easy_setopt(curl, CURLOPT_READDATA, fd);
/* and give the size of the upload (optional) */
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)file_info.st_size);
/* enable verbose for easier tracing */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
/* Check for errors */
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
else {
/* now extract transfer info */
curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
fprintf(stderr, "Speed: %.3f bytes/sec during %.3f seconds\n",
speed_upload, total_time);
}
/* always cleanup */
curl_easy_cleanup(curl);
}
system("pause");
return 0;
}
上传文件:
#include "httpcurl.h"
#include <stdio.h>
#include <curl/curl.h>
#include <sys/stat.h>
#include <fcntl.h>
static const int OPEN_FILE_ERROR = 100;
static const int FILE_SIZE_ZERO = 101;
namespace httpcurl {
struct WriteThis {
FILE *fd;
long size;
};
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{
struct WriteThis *pooh = (struct WriteThis *)userp;
if (size*nmemb < 1) {
return 0;
}
size_t readSize = fread(ptr, size, nmemb, pooh->fd);
pooh->size -= readSize;
return readSize;
}
int UploadFileSync(const std::string &url, const std::string &filePath)
{
CURL *curl;
CURLcode res;
struct stat file_info;
struct WriteThis pooh;
pooh.fd = fopen(filePath.c_str(), "rb");
if (!pooh.fd) {
return OPEN_FILE_ERROR;
}
fstat(_fileno(pooh.fd), &file_info);
pooh.size = file_info.st_size;
if (pooh.size == 0) {
return FILE_SIZE_ZERO;
}
/* In windows, this will init the winsock stuff */
res = curl_global_init(CURL_GLOBAL_DEFAULT);
/* Check for errors */
if (res != CURLE_OK) {
return res;
}
/* get a curl handle */
curl = curl_easy_init();
if (curl) {
/* First set the URL that is about to receive our POST. */
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
/* Now specify we want to POST data */
curl_easy_setopt(curl, CURLOPT_POST, 1L);
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
/* pointer to pass to our read function */
curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
/* get verbose debug output please */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/*
If you use POST to a HTTP 1.1 server, you can send data without knowing
the size before starting the POST if you use chunked encoding. You
enable this by adding a header like "Transfer-Encoding: chunked" with
CURLOPT_HTTPHEADER. With HTTP 1.0 or without chunked transfer, you must
specify the size in the request.
*/
#ifdef USE_CHUNKED
{
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
/* use curl_slist_free_all() after the *perform() call to free this
list again */
}
#else
/* Set the expected POST size. If you want to POST large amounts of data,
consider CURLOPT_POSTFIELDSIZE_LARGE */
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, file_info.st_size);
#endif
#ifdef DISABLE_EXPECT
/*
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue"
header. You can disable this header with CURLOPT_HTTPHEADER as usual.
NOTE: if you want chunked transfer too, you need to combine these two
since you can only set one list of headers with CURLOPT_HTTPHEADER. */
/* A less good option would be to enforce HTTP 1.0, but that might also
have other implications. */
{
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "Expect:");
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
/* use curl_slist_free_all() after the *perform() call to free this
list again */
}
#endif
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
}
curl_global_cleanup();
fclose(pooh.fd);
return res;
}
std::string GetErrorStr(int err)
{
if (err > CURLE_OK && err < CURL_LAST) {
return curl_easy_strerror((CURLcode)err);
}
switch (err) {
case 0:
return "success";
break;
case OPEN_FILE_ERROR:
return "open file error";
break;
case FILE_SIZE_ZERO:
return "file size is zero";
break;
default:
return "unkown";
break;
}
}
}