3

Я использую libcurl У меня есть загрузка файлов внутри класса, на которые я хочу увидеть функцию прогресса. Я заметил, что я могу установить типичный указатель на функцию с помощьюКак я могу использовать указатель функции-члена в libcurl

curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, progress_func3); 

Однако, я хотел бы, чтобы установить его в функцию указатель на мой класс. Я могу получить код для компиляции с

curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, &MyClass::progress_func3); 

и функция progress_func3 будет вызвана. Проблема в том, что, как только он вернется, будет обнаружен «переполнение буфера»! ошибка, заявив, что программа не может безопасно продолжать и выполнять, и должна быть прекращена. (Это окно ошибки Microsoft Visual C++ Runtime Library, я использую Visual Studio 2010).

Когда я использую функцию, нет никаких проблем, но когда я использую указатель на функцию-член, я получу эту ошибку. Как я могу использовать указатель функции-члена в libcurl?

ответ

5

Для нестатической функции-члена требуется указатель this для вызова. Вы не можете указать, что указатель this с этим типом интерфейса, поэтому использование нестатической функции-члена невозможно.

Вы должны создать функцию «plain C» в качестве своего обратного вызова, и эта функция вызовет функцию-член в соответствующем экземпляре MyClass.

Попробуйте что-то вроде:

int my_progress_func(void *clientp, ...) 
{ 
    MyClass *mc = static_cast<MyClass*>(clientp); 
    mc->your_function(...); 
    return 0; // or something else 
} 

Тогда:

curl_easy_setopt(mCurl, CURLOPT_PROGRESSDATA,  &your_myclass_object); 
curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, my_progress_func); 

(Вы ответственны за матч типа здесь, очевидно, если вы приложите что-нибудь еще, кроме MyClass указатель на данные о ходе работы. , вы по своему усмотрению.)

+0

Как я могу позвонить классу? Функция прогресса имеет предопределенные параметры, которые автоматически отправляются – judeclarke

+0

Вы видели мое редактирование? – Mat

+0

Я должен был просто нажать обновление на странице в неподходящее время. Это отлично работает, спасибо. – judeclarke

1

Это можно использовать boost :: bind(). Например:

boost::bind(&MyClass::progress_func3, this); 

- указатель на метод, который возвращает void и не имеет аргументов. Если обратный вызов необходимо аргументы, используйте заполнители следующим образом:

boost::bind(&MyClass::progress_func3, this, _1, _2) 

this указатель может быть заменен с точкой к экземпляру MyClass.

EDIT: Вы должны иметь возможность использования boost :: function <> и функции ptr типов относительно взаимозаменяемы. Например:

typedef boost::function< void (int, short) > Callback; 

эквивалентно

typedef void (Callback)(int); 

Вы, возможно, придется слой его с помощью функции между ними, чтобы сделать компилятор счастливым. Я знаю, что я определил обратный вызов с использованием boost :: function <> и передал его в виде обычного указателя функции.

+0

Как вам это удается? Кажется, я не могу найти способ передать функцию boost :: как обратный вызов. – Mat

Смежные вопросы