我在 stackoverflow 上阅读了一些关于 c++/curl 的文章,并整理了以下内容。 主要目标是在一个类的实例中处理整个请求——可能稍后在辅助线程中处理。
我的问题是:“content_”似乎保持为空,尽管它具有相同的地址和
HttpFetch.h:
class HttpFetch
{
private:
CURL *curl;
static size_t handle(char * data, size_t size, size_t nmemb, void * p);
size_t handle_impl(char * data, size_t size, size_t nmemb);
public:
std::string content_;
static std::string url_;
HttpFetch(std::string url);
void start();
std::string data();
};
HttpFetch.cpp:
HttpFetch::HttpFetch(std::string url) {
curl_global_init(CURL_GLOBAL_ALL); //pretty obvious
curl = curl_easy_init();
content_.append("Test");
std::cout << &content_ << "\n";
curl_easy_setopt(curl, CURLOPT_URL, &url);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &content_);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &HttpFetch::handle);
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //tell curl to output its progress
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
//std::cout << &content_ << "\n";
}
void HttpFetch::start() {
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
size_t HttpFetch::handle(char * data, size_t size, size_t nmemb, void * p)
{
std::string *stuff = reinterpret_cast<std::string*>(p);
stuff->append(data, size * nmemb);
std::cout << stuff << "\n"; // has content from data in it!
return size * nmemb;
}
主要.cpp:
#include "HttpFetch.h"
int main(int argc, const char * argv[])
{
HttpFetch call = *new HttpFetch("http://www.example.com");
call.start();
::std::cout << call.content_ << "\n"
}
提前致谢
最佳答案
您的代码有几个问题。主要问题是线路
HttpFetch call = *new HttpFetch("http://www.example.com");
您创建一个新的 HttpFetch 实例并将其复制到另一个实例。所以你有两个实例和两个内容字符串。要消除此问题,请将其更改为:
HttpFetch call("http://www.example.com");
另一个错误是行
curl_easy_setopt(curl, CURLOPT_URL, &url);
应该是
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
如果您考虑过像 HttpFetch 这样的类中的资源管理,您就可以避免此类问题。由于 HttpFetch 管理资源(curl 句柄),您必须考虑如何初始化和清理该资源以及如何处理复制、分配或移动。如果您使用 C++11,最简单的解决方案是使用 std::unique_ptr
来为您处理所有这些事情。
class HttpFetch
{
public:
HttpFetch(const std::string& url);
void start();
void Print(std::ostream& stream);
private:
typedef void (*cleanup)(CURL*);
typedef std::unique_ptr<CURL, cleanup> CurlHandle;
CurlHandle curlHandle;
std::string content_;
static size_t handle(char * data, size_t size, size_t nmemb, void * p);
};
HttpFetch::HttpFetch(const std::string& url)
: curlHandle(curl_easy_init(), &curl_easy_cleanup)
{
curl_easy_setopt(curlHandle.get(), CURLOPT_URL, url.c_str());
curl_easy_setopt(curlHandle.get(), CURLOPT_WRITEDATA, &content_);
curl_easy_setopt(curlHandle.get(), CURLOPT_WRITEFUNCTION, &HttpFetch::handle);
curl_easy_setopt(curlHandle.get(), CURLOPT_FOLLOWLOCATION, 1L);
}
size_t HttpFetch::handle(char * data, size_t size, size_t nmemb, void * p){
std::string *stuff = static_cast<std::string*>(p);
stuff->append(data, size * nmemb);
return size * nmemb;
}
void HttpFetch::start() {
content_.clear();
curl_easy_perform(curlHandle.get());
}
void HttpFetch::Print(std::ostream& stream){
stream << content_;
}
int main()
{
//HttpFetch call = *new HttpFetch("..."); // this is a copiler error now
HttpFetch call("http://www.google.com");
call.start();
call.Print(std::cout);
}
使用 unique_ptr
您的类 HttpFetch 变得不可复制且只能移动。在您提供在 HttpFetch 的不同实例之间复制或共享 CURL 句柄的逻辑之前,这是有意义的。
关于c++ - c++ 类中的 curl 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13661878/