I am trying to learn how to call this write_data(…) function from the funmain() function in the class as shown in the code bellow. (I know this program works if I just list these two functions without putting it inside a class).
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data) line gives me error and wouldn’t let me call the write_data(…) function. Can you please correct my code and tell me how I can achieve this. Any help would be greatly appreciated. Thanks.
error C3867: 'go_website::write_data': function call missing argument list; use '&go_website::write_data' to create a pointer to member
//Microsoft Visual Studio 10 in C++
#define CURL_STATICLIB
#include <stdio.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <iostream>
#include <curl/easy.h>
#include <string>
using namespace std;
extern "C" typedef size_t curl_write_callback(void *ptr, size_t size, size_t nmemb, FILE *stream);
class go_website
{
public:
static curl_write_callback write_data;
void funmain()
{
CURL *curl;
FILE *fp;
CURLcode res;
char *url = "http://www.shorturl.com/";
char outfilename[FILENAME_MAX] = "C:\\bbb.txt";
curl = curl_easy_init();
if (curl) {
fp = fopen(outfilename,"wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_data);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
}};
extern "C" size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
int main()
{
go_website a;
a.funmain();
return 0;
}
These two lines won’t work:
The second is the easiest to fix:
fpis a file pointer, not a function, you’re setting the wrong attribute, I guess you wantCURLOPT_WRITEDATA.For the callback function, you need a function pointer. The name of an ordinary function automatically decays to its address, although using the address-of operator (
&functionname) is cleaner.Class member functions do not automatically decay. In fact, a non-static class member function is totally incompatible with a normal function pointer, since there’s no way to handle
this. Luckily you don’t need a non-static member function, since no non-static members are used inside the callback.Make the callback function
staticandextern "C":and then take its address, using the address-of operator and fully-qualified function name:
This part was even explained in the error message. But it didn’t tell you that you needed
staticorextern "C", this is the problem with variable argument lists, they aren’t typesafe.After reading the Standard (section 7.5
[dcl.link], and especially paragraph 4 and its examples), this isn’t allowed. The member function still has C++ language linkage, for both its name (not important) and its type (this is the deal-breaker).You have to use a global function for the callback:
and then pass a pointer to it: