c++ - c++ 类中的 curl 问题

标签 c++ curl

我在 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/

相关文章:

perl - 转储 WWW::Curl::简单请求

php - 如何使用 wget 或curl 以类似于浏览器的方式从 CLI 执行 PHP 脚本

curl - curl 以提示用户名和密码

php - 使用来自 SSL 服务器的 Curl 下载 xml 提要?

python-2.7 - 将curl示例转换为pycurl

c++ - 递归期间的数组与 vector

c++ - 需要帮助使用 C++ 在 Linux 环境中为现有应用程序生成击键

c++ - 生成一波敌人 C++

c++ - 为什么我应该使用 1 位位字段而不是书籍?

c++ - 找到MFC Dialog的当前位置