2016-03-20 28 views
1

Kullanıcı talebi (konsol) almak ve bu isteği başlıklarda (libcurl) bir web sitesine göndermek ve yanıt başlıklarını almak için çok basit bir program yapmaya çalışıyorum.Libcurl C++ ile bellek erişim hatası

Yani 2 sınıfları (I sınıfların bir sürü var aslında ama burada sorun için ben basitleştirecek)

Benim main.cpp isteği almak ve benim servisine gönderin.

Yani burada benim hizmet Fuzzer.h geçerli:

#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 

ve burada benim Fuzzer.cpp geçerli:

#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; 
    } 
} 

Ama bu yürütmeye çalıştığımda bir bellek hatası var. Bu nedenle :

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

Projem için libcurl kullanıyorum. Bunun bir C kütüphanesi olduğunu biliyorum, belki sorun değil mi? libcurl callbacks w/c++ class members

ve bu bir: bana yardım etmek için

Ben tezler talimatları takip Ben Windows 7 üzerinde olduğum curl WRITEFUNCTION and classes ve Visual Studio 2013

(PS var: Ben koyduğunuzda bu . herhangi bir sorun olmadan çalışır & fuzzer :: writeH ve main.cpp içindeki statik fonksiyonu olmadan kodu)

+1

Nasıl hatta derler? Statik olmayan üye bir işlevi kullanamazsınız. –

cevap

1

sorunun burada olduğunu düşünüyorum:

doğru belirtildiği gibi
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Fuzzer::writeH); 

, libcurl C kütüphanesidir, ancak elemanı işlevi curl_easy_setopt fonksiyonu için bir işaretçi geçmektedir. Şimdi, bir sınıfın üyelerine gösterici işaretçiler ve işaretçiler farklı türlerdir, bu yüzden bunu yapamazsınız. Bildiğim tek çözüm, trambolin araması kullanıyor.

  • Eğer curl_easy_setopt içinde geri arama kaydedecektir düz fonksiyonu (sınıfınızın olmayan üye) oluştur()
  • sınıfın trambolin geri arama arkadaş olun (böylece gerekirse o özel üyelerine erişmesi olabilir)
  • callback'inde geçirilen userdata argüman size sınıf işaretçi geri döküm ve istenen üye işlev (ler)
01 arayacak trambolin callback'inde içine sınıfınızın
  • için işaretçi olmalıdır Örnek olarak

    :

    extern "C" size_t trampolineCallback(char * i_buffer, size_t i_size, size_t i_nitems, void * i_userdata); 
    

    sınıf uygulamasında gibi bir şey olacaktır:

    curl_easy_setopt(m_curlHndlPtr, CURLOPT_HEADERDATA, (void*) this); 
    curl_easy_setopt(m_curlHndlPtr, CURLOPT_HEADERFUNCTION, trampolineCallback); 
    

    Kişisel trambolin uygulaması gibi görünecektir:

    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); 
    } 
    
  • +0

    Hmm, Tamam Ben sadece noktayı görmeye başladım (tamam çok yavaşım). Ama "C" ne anlamadım? extern "C" –

    +1

    @VincentRasquier [extern "C"] (http://stackoverflow.com/q/1041866/1362568) –

    +0

    @MikeKinghan teşekkürler mutch! Sizler mükemmelsiniz! Eh, "C" ve diğer C++ şeyleri bilmiyorum daha fazla ayrıntı ile öğrenmek zorundayız ... gerçek teşekkür ederim! Everythink çalışıyor! –