3

我正在使用 libcurl 我在一个类中下载了文件,我想看到一个进度功能。我注意到我可以设置一个典型的函数指针

curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, progress_func3);

但是,我想将它设置为指向我的类的函数指针。我可以得到代码来编译

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

并且该progress_func3函数将被调用。问题是,一旦它返回,就会出现“检测到缓冲区溢出!” 错误通过,表示程序不能安全地继续执行,必须终止。(这是一个 Microsoft Visual C++ 运行时库错误窗口,我使用的是 Visual Studio 2010)。

当我使用函数时,没有问题,但是当我使用成员函数指针时,我会得到这个错误。如何在 libcurl 中使用成员函数指针?

4

3 回答 3

5

非静态成员函数需要一个this可调用的指针。您不能为this这种类型的接口提供该指针,因此无法使用非静态成员函数。

您应该创建一个“普通 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指向进度数据的指针之外的任何其他内容,那么您就只能靠自己了。)

于 2012-04-11T17:33:44.590 回答
1

你可以使用 boost::bind() 来实现。例如:

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

是一个指向返回 void 且没有参数的方法的指针。如果您的回调需要参数,请使用占位符,如下所示:

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

指针可以替换为this指向MyClass.

编辑:您应该能够使用 boost::function<> 和函数 ptr 类型相对可互换。例如:

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

相当于

typedef void (Callback)(int);

您可能必须在其间添加一个函数以使编译器满意。我知道我已经使用 boost::function<> 定义了一个回调并传入了一个常规函数指针。

于 2012-04-11T17:36:53.137 回答
0

类实例“this”有效:

static int progressCallback( void * p, double dltotal, double dlnow, double ultotal, double ulnow )
{
    QTWindow * w{ static_cast< QTWindow * >( p ) };
    emit w->uploadProgressData( ulnow, ultotal );
    return 0;
}

curl_easy_setopt( curl, CURLOPT_NOPROGRESS, 0L );
curl_easy_setopt( curl, CURLOPT_PROGRESSFUNCTION, progressCallback );
curl_easy_setopt( curl, CURLOPT_PROGRESSDATA, this );
于 2021-05-28T09:12:02.910 回答