如何在libcurl中使用成员函数指针

时间:2012-04-11 17:28:54

标签: c++ curl function-pointers libcurl member-function-pointers

我正在使用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中使用成员函数指针?

3 个答案:

答案 0 :(得分: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指针之外的任何其他内容,那么你自己就可以了。)

答案 1 :(得分:1)

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

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

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

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

this指针可以替换为MyClass实例的指针。

编辑: 你应该可以使用boost :: function&lt;&gt;和函数ptr类型相对可互换。例如:

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

相当于

typedef void (Callback)(int);

您可能必须使用中间的函数对其进行分层,以使编译器满意。我知道我已经使用boost :: function&lt;&gt;定义了一个回调并传入常规函数指针。

答案 2 :(得分:0)

类实例“this”有效:

const GetItem = (
    item: string | PrivilegeConditionOperator | PrivilegeConditionElement | Privilege,
    index: number
) => {
        if (item instanceof PrivilegeConditionElement)
            return `PrivilegeContionElement ${index}`;
        else if (item instanceof Privilege)
            return `Privilege ${index}`;
        else if (item instanceof PrivilegeCondition)
            return `PrivilegeContion ${index}`;
        else if (item instanceof PrivilegeConditionOperator)
            return item.name;
        else
            return item;
    
};