0

I figured out how to get curl to POST and GET to a webpage. It was working fine and writing the stream to a file perfectly. Now I am trying to convert it to a class called DownloadFile. The end result being able to call member functions like:

download.HTTPPOST(http, postData, filename);

I have the following code in the HTTPPOST member function:

void DownloadFile::HTTPPOST(const char * http, const char *postData, std::string filePath)
{
    CURL *curl;
    CURLcode res;
    std::ofstream fout;
    fout.open(filePath, std::ofstream::out | std::ofstream::app);

    /* In windows, this will init the winsock stuff */
    curl_global_init(CURL_GLOBAL_ALL);

    /* get a curl handle */
    curl = curl_easy_init();
    if (curl) 
    {
        /* First set the URL that is about to receive our POST. This URL can
        just as well be a https:// URL if that is what should receive the
        data. */
        curl_easy_setopt(curl, CURLOPT_URL, http);

        /* Now specify the POST data */
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);

        /* send all data to this function  */
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);

        /* we pass our 'chunk' struct to the callback function */
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fout);

        /* Perform the request, res will get the return code */
        res = curl_easy_perform(curl);

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

        /* always cleanup */
        curl_easy_cleanup(curl);
    }
    curl_global_cleanup();

    DownloadFile::setStatus(res);
}

This is the code I have for the write_callback member function:

size_t DownloadFile::write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    std::ofstream *fout = (std::ofstream *)userdata;
    for (size_t x = 0; x < nmemb; x++)
    {
        *fout << ptr[x];
    }

    return size * nmemb;
}

When I try to build this I get an error:

error C3867: 'DownloadFile::write_callback': non-standard syntax; use '&' to create a pointer to member

Passing the write_callback function by address was working fine before? I did what it suggested '&' operator before the function and recived this error:

error C2276: '&': illegal operation on bound member function expression

I am at a loss trying to figure this out. Why doesn't it recognize the write_callback as an memory address? I am now under the impression that it doesn't have a memory address at compile time so it's confused or something? Any help would be appreciated.

Thanks.

  • The callback function won't be called with a `this` parameter. You need to use a static member or `std::bind()` to bind it to `this`. – Barmar Sep 20 '16 at 16:31
  • And C++ doesn't allow automatic conversions to `void*`, you need an explicit cast. – Barmar Sep 20 '16 at 16:32
  • 1
    Possible duplicate of [C++ class member function and callback from C API](http://stackoverflow.com/questions/9246719/c-class-member-function-and-callback-from-c-api) – Barmar Sep 20 '16 at 16:33
  • Setting write_callback as static worked. I have no idea where to begin with std::bind(), I haven't even touched the idea of function templates. You say that C++ doesn't allow auto conversions but it is working without it. I will change it anyway but then why is it working? – ProfounDisputes Sep 20 '16 at 16:49
  • Why would C++ need to know the type to cast into void type? It can take any type because its void I thought? – ProfounDisputes Sep 20 '16 at 16:52
  • C++ doesn't allow implicit type casting, you have to write `(void*)`. Also, since `curl_easy_setopt` is a variadic function, it doesn't know the destination type. – Barmar Sep 20 '16 at 17:01
  • So what you're saying is the reason why it is working is because curl_easy_setopt is a variadic function so it will accept any extra values? So somewhere in the code they take that value with va_arg and casts it into (void *), since WRITEDATA requires that to be a (void *). That makes sense why it is working without the explicit type cast. – ProfounDisputes Sep 20 '16 at 17:14
  • Yes, that's what's happening. – Barmar Sep 20 '16 at 17:29
  • Also covered in the curl FAQ already: https://curl.haxx.se/docs/faq.html#Using_C_non_static_functions_f – Daniel Stenberg Sep 21 '16 at 10:59

0 Answers0