libcurl 回调 w/c++班级成员

发布于 2024-12-13 10:43:50 字数 629 浏览 1 评论 0原文

摘自 libcurl 站点上的 libcurl 编程教程

使用 C++ 的 libcurl

使用 C++ 时基本上只需记住一件事 在连接 libcurl 时而不是 C:

回调不能是非静态类成员函数

C++ 代码示例:

AClass 类 
{   
    静态 size_t write_data(void *ptr, size_t size, size_t nmemb, void ourpointer)       
    { /* 对数据做你想做的事 */ }  
}

这个限制是什么,是范围问题吗?如果每个类成员都有自己的 easy_handle 那么它可以使用对其自己的非静态成员函数的回调吗?就不再继续说了。无论哪种方式我都可以使用它,但我很好奇它为什么存在。

编辑:还有一件事;这是否会对从类中创建 easy_handle 施加限制?如果是这样的话,这会给我的设计带来很大的问题,我希望每个对象都有自己的 easy_handle。

Taken from the libcurl programming tutorial on the libcurl site:

libcurl with C++

There's basically only one thing to keep in mind when using C++
instead of C when interfacing libcurl:

The callbacks CANNOT be non-static class member functions

Example C++ code:

class AClass 
{   
    static size_t write_data(void *ptr, size_t size, size_t nmemb,   void ourpointer)       
    {   /* do what you want with the data */   }  
}

What is this limitation for, is it a problem of scope? If each class member has it's own easy_handle then can it then use callbacks to it's own non static member functions? It doesn't go on to say. I can work with this either way, but I'm curious why it exists.

edit: One more thing; does this impose a limitation on creating easy_handle's from within a class? That would greatly pose a problem for my design if so, I'd like each object to have its own easy_handle.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雾里花 2024-12-20 10:43:50

非静态成员函数通常不允许作为 C 回调,因为它还需要实例指针作为隐藏参数,而调用 C 代码未提供该参数(并且此隐藏参数取决于编译器,可能无法传递根据“常规”调用约定,但在特定寄存器中,...)。

相反,静态成员函数是具有特定范围的“正常”函数(就 ABI 而言,这不相关)。

A non-static member function is normally not allowed as a C callback because it needs also the instance pointer as a hidden parameter, which is not provided by the calling C code (and this hidden parameter, depending from the compiler, may not be passed according to the "regular" calling convention, but in a particular register, ...).

Static member functions, instead, are "normal" functions with a particular scope (which is not relevant as far as the ABI is concerned).

奈何桥上唱咆哮 2024-12-20 10:43:50

要调用实例方法,您需要一个实例来调用它。接受函数指针的 libcurl 函数并不接受对象指针(相反,不能,因为它们是 C 函数),因此无法传递调用实例方法所需的数据。

您可以通过 userdata 参数传递实例指针,然后使用它来调用实例方法:

class AClass {
public:
    static size_t invoke_write_data
        (void *data, size_t size, size_t nmemb, void* pInstance)       
    {
        return ((AClass*)pInstance)->write_data(ptr, size, nmemb);
    }

    size_t write_data(void *data, size_t size, size_t nmemb) {
        /* ... */
    }
};

...
    extern AClass instance;

    curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, AClass::invoke_write_data);
    curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &instance);

如果您需要通过 userdata 参数传递更多数据,请使用以下结构:包括实例指针作为成员。请小心内存管理:参数结构可能最终会泄漏或被提前回收。

当 C++0x 成为标准并受到编译器支持时,您应该能够使用闭包来绑定实例和实例方法,并传递匿名函数作为回调。

另请参阅:“如何传递指针-信号处理程序的成员函数、X 事件回调、启动线程/任务的系统调用等?”来自 C++ 常见问题解答。

To call an instance method, you need an instance to call it on. The libcurl functions that take function pointers don't also take object pointers (rather, can't, since they're C functions), so there's no way of passing the requisite data to call an instance method.

You can pass an instance pointer via the userdata argument, then use that to invoke an instance method:

class AClass {
public:
    static size_t invoke_write_data
        (void *data, size_t size, size_t nmemb, void* pInstance)       
    {
        return ((AClass*)pInstance)->write_data(ptr, size, nmemb);
    }

    size_t write_data(void *data, size_t size, size_t nmemb) {
        /* ... */
    }
};

...
    extern AClass instance;

    curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, AClass::invoke_write_data);
    curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &instance);

If you need to pass more data via the userdata argument, use a struct that includes the instance pointer as a member. Be careful about memory management: the argument struct could end up leaking or being reclaimed early.

When C++0x becomes standard and supported by compilers, you should be able to make use of closures to bind an instance and instance method, passing an anonymous function as the callback.

See also: "How do I pass a pointer-to-member-function to a signal handler, X event callback, system call that starts a thread/task, etc?" from the C++ FAQ.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文