4

I am trying to pass a lambda to the CURLOPT_WRITEFUNCTION.

The function expects a static function, however, I learned from this question that a lambda would be implicitly converted, and I could call the member function from the lambda.

auto callback = [](char * ptr_data, size_t size, size_t nmemb, string * writerData)
->size_t
{
    if(writerData == NULL)
        return 0;
    size_t data_size = size * nmemb;
    writerData->append(ptr_data, data_size);
    return (int)data_size;
};

CURLcode code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, callback);

This actually compiles, but curl segfaults: Segmentation fault: 11

I pasted the full example here.

Community
  • 1
  • 1
Francisco Aguilera
  • 3,099
  • 6
  • 31
  • 57
  • Looking at your snippet, don't you want: `code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer);` to be called before you call `CURLOPT_WRITEFUNCTION`? Otherwise the pointer to pass to the callback is not set. – Jesse Good Apr 13 '15 at 03:00
  • @JesseGood, The order doesn't matter as long as I set them before calling `curl_easy_perform`. – Francisco Aguilera Apr 13 '15 at 03:04

2 Answers2

8

The magic is, add the leading "+" at the non-captured lambda expression, which will trigger conversion to plain C function pointer.

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
  /* NOTE: Leader '+' trigger conversion from non-captured Lambda Object to plain C pointer */
  +[](void *buffer, size_t size, size_t nmemb, void *userp) -> size_t {
    // invoke the member function via userp
    return size * nmemb;
  });

My understanding is, curl_easy_setopt wants a void*, not an explicit function type, so the compiler just gives the address of lambda object; if we do a function pointer operation on lambda object, the compiler will return the function pointer from lambda object.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Sunline
  • 126
  • 1
  • 4
3

A lambda closure is convertible to a function pointer only if the lambda has no captures.

Your lambda is capturing [this] so it cannot be converted.

Edit: this was an answer to the original revision of the question.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • While not curl specific, [these](http://stackoverflow.com/questions/15657011) other [questions](http://stackoverflow.com/questions/28746744) are similar. – Drew Dormann Apr 13 '15 at 02:23
  • see my edit, I was aware of this, and was testing different configurations, because curl still segfaults in all cases. – Francisco Aguilera Apr 20 '15 at 12:12