curl-library
Re: Callback function gives crazy "size_t nmemb" value for simple http get operation (C++)
Date: Sun, 5 Apr 2009 10:12:40 -0400
2009/4/5 Phil Blundell <pb_at_reciva.com>:
> On Sun, 2009-04-05 at 09:29 +0200, Kjetil Volden wrote:
>> curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Book::write_html);
>
> This is your problem; the WRITEFUNCTION expects a pointer to a C
> function, not a C++ method. You need to provide a wrapper function to
> interface between the C and C++ worlds, or make Book::write_html be a
> static member function rather than an object method.
The easiest thing to do in C++ is to pass a pointer to a static
method. It needs to have the correct prototype, so you should declare
it in the header as:
static size_t write_html(char *buffer, size_t size, size_t nmemb, void *ptr);
and in the .cpp (or .cc) as:
size_t Book::write_html(char *buffer, size_t size, size_t nmemb, void* ptr) {
std::string *html = (std::string*)ptr;
int result = 0;
if(buffer != NULL){
html->append(buffer, size*nmemb);
result = size*nmemb;
}
return result;
}
A fairly common thing to do if your callback needs to be a non-static
method is to pass the this pointer as the data, and use a static
wrapper. For example, if write_html needed to be non-static, then you
should have two methods in the Book class:
static size_t write_html_callback(char *buffer, size_t size, size_t
nmemb, void* thisPtr) {
if (thisPtr)
return (Book*)thisPtr->write_html(buffer, size, nmemb);
else
return 0;
}
size_t write_html(char* buffer, size_t size, size_t nmemb);
// Presumably, the place to write the html to would be stored in a
private member variable somewhere
// in the Book class
In this case, you would call it with:
Book book;
...
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Book::write_html_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &book);
It is more common to have the code for setting up the callback in the
same class as the callback, in which case you could do:
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_html_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
-Craig
Received on 2009-04-05