首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用libcurl C++的内存访问错误

使用libcurl C++的内存访问错误
EN

Stack Overflow用户
提问于 2016-03-20 16:00:50
回答 1查看 729关注 0票数 1

我试图做一个非常简单的程序,得到一个用户请求(控制台),并将此请求发送到一个网站的标题(libcurl),然后得到响应头。

所以我有两个类(事实上,我有很多类,但是对于这里的问题,我会简化)

我的main.cpp收到请求并将其发送给我的服务。

这是我的服务,Fuzzer.h:

代码语言:javascript
复制
#ifndef FUZZER_H
#define FUZZER_H

#include <string>

using namespace std;

namespace furez 
{
    class Fuzzer {
    private:
        string url;
        string response;
        static size_t writeH_static(void *, size_t, size_t, void *);

    public:
        Fuzzer(string);
        virtual ~Fuzzer();
        string sendRequest(string);
        size_t writeH(void *, size_t, size_t);
    };

}

#endif

这是我的Fuzzer.cpp:

代码语言:javascript
复制
#include <string>
#include <curl/curl.h>
#include <iostream>

#include "Fuzzer.h"

namespace furez 
{
    Fuzzer::Fuzzer(std::string u) 
    {
        this->url = u;
    }

    Fuzzer::~Fuzzer(){}

    string Fuzzer::sendRequest(std::string request) 
    {
        CURL *curl;
        CURLcode res;

        static const char *headerfilename = "head.out";
        static const char *bodyfilename = "body.out";

        curl = curl_easy_init();
        if (curl) {
            struct curl_slist *chunk = NULL;

            chunk = curl_slist_append(chunk, "Accept:");
            chunk = curl_slist_append(chunk, "Another: yes");
            chunk = curl_slist_append(chunk, "Host: example.com");
            chunk = curl_slist_append(chunk, "X-silly-header;");

            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Fuzzer::writeH);

            Fuzzer instance(request);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &instance);

            curl_easy_setopt(curl, CURLOPT_URL, "localhost");

            res = curl_easy_perform(curl);
            /* Check for errors */
            if (res != CURLE_OK) {
                fprintf(stderr, "curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));
            }

            curl_easy_cleanup(curl);
            curl_slist_free_all(chunk);
        }

        return request;
    }

    size_t Fuzzer::writeH_static(void *ptr, size_t size, size_t nmemb, void *stream)
    {
        return ((Fuzzer*)stream)->writeH(ptr, size, nmemb);
    }

    size_t Fuzzer::writeH(void *ptr, size_t size, size_t nmemb)
    {
        //std::string str = (CHAR *)ptr;
        //std::string str2("Server:");

        //if (str.find(str2) != string::npos) {
            //this->response = str;
        //}

        size_t realsize = size * nmemb;
        return realsize;
    }
}

但是当我尝试执行这个时,我得到了一个内存错误。正因如此:

代码语言:javascript
复制
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Fuzzer::writeH);

我在我的项目中使用了libcurl。我知道这是个C库也许是问题所在?

为了帮助我,我遵循了这些说明:libcurl callbacks w/c++ class members

这一个是:curl WRITEFUNCTION and classes,我在Windows 7上,得到了Visual 2013。

(PS:当我在main.cpp中放置这段代码时,没有&Fuzzer:writeH和静态函数,它的工作没有任何问题。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-20 16:19:27

我认为问题在于:

代码语言:javascript
复制
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Fuzzer::writeH);

正如您正确地指出的,libcurl是一个C库,但是您要向函数curl_easy_setopt传递指向成员函数的指针。现在,函数指针和指向类成员的指针是不同的类型,因此不能这样做。我知道的唯一解决方案是使用蹦床调用

  • 创建一个普通函数(类的非成员),将其注册为curl_easy_setopt()中的回调函数
  • 让蹦床回访成为你类的朋友(如果需要的话,她可以访问私人成员)
  • 传递给回调的userdata参数应该是指向类的指针。
  • 在蹦床回调中,您将把指针转换回类,并调用所需的成员函数。

例如:

代码语言:javascript
复制
extern "C" size_t trampolineCallback( char * i_buffer, size_t i_size, size_t i_nitems, void * i_userdata );

在您的类实现中,您将得到如下内容:

代码语言:javascript
复制
curl_easy_setopt( m_curlHndlPtr, CURLOPT_HEADERDATA, (void*) this );
curl_easy_setopt( m_curlHndlPtr, CURLOPT_HEADERFUNCTION, trampolineCallback );

您的蹦床实现将类似于:

代码语言:javascript
复制
size_t trampolineCallback(char *i_buffer, size_t i_size, size_t i_nitems, void *i_userdata)
{
    MyObj * object = (MyObj*) i_userdata;
    object->myMemberFunc( i_buffer,i_size, i_nitems );
    return (i_size * i_nitems);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36116041

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档