Эти две строки не будут работать:
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fp);
Второе проще всего исправить: fp
это указатель файла, а не функция, вы устанавливаете неправильный атрибут, я думаю, вы хотите CURLOPT_WRITEDATA
.
Для функции обратного вызова вам нужен указатель на функцию. Имя обычной функции автоматически распадается на ее адрес, хотя использование оператора адреса (&functionname
) более чисто.
Функции-члены класса не исчезают автоматически. Фактически, нестатическая функция-член класса полностью несовместима с обычным указателем на функцию, поскольку нет способа обработать this
. К счастью, вам не нужна нестатическая функция-член, поскольку внутри обратного вызова не используются нестатические члены.
Сделайте функцию обратного вызова static
и extern "C"
:
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;
// ...
};
extern "C" size_t go_website::write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
, а затем взять его адрес, используя адрес оператора и полное имя функции:
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &go_website::write_data);
Эта часть была даже объяснена в сообщении об ошибке. Но он не говорил вам, что вам нужно static
или extern "C"
, это проблема списков переменных аргументов, они не безопасны для типов.
После прочтения Стандарта (раздел 7.5 [dcl.link]
, и особенно параграф 4 и его примеры) это не разрешено. Функция-член по-прежнему имеет связь с языком C ++ как для своего имени (не важно), так и для его типа (это прерыватель сделки).
Вы должны использовать глобальную функцию для обратного вызова:
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;
}
и затем передайте на него указатель:
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_data);