C++11 中的 C 风格回调

2024-01-03

在 C++11 项目中,我使用需要 C 风格回调的 C 风格第三方库(在我的例子中为curl)。

为了实现这一点,我使用了“指向成员的指针”运算符:

size_t c_callback_wrapper(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    MyClass *p = (MyClass*)userdata;
    return (p->*&MyClass::actualCallback)(ptr, size, nmemb, userdata);
}


void Myclass::performSomething() {
    // register callback function
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, c_callback_wrapper);
    // register userdata
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
    ...
    res = curl_easy_perform(curl);
}

这个解决方案确实有效,但对我来说并不令人满意。

我真正想做的是在我的注册函数中编写一个 lambda。

一般来说,优点是局部性:我将能够捕获一些局部变量,并且不需要编写复杂的“actualCallback”成员例程。

我已经读到,当 Lambda 捕获变量时,似乎不可能将其用作 C 风格函数。

有没有什么方法可以通过一些技巧来实现这一目标? (例如,使用 lambda 的调用约定,...)

Thanks


捕获上下文变量的 lambda 无法转换为裸函数指针,因为这将导致无法携带捕获的状态。您在示例中展示的是处理通过 C 回调调用 C++ 成员函数问题的正确方法。

你可以替换c_callback_wrapper如果您发现更有吸引力的话,可以使用 capture less lambda。

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, 
                 [](char *ptr, size_t size, size_t nmemb, void *userdata) {
                    // invoke the member function via userdata
                    auto p = static_cast<MyClass *>(userdata);
                    return p->actualCallback(ptr, size, nmemb, userdata);
                 });

请注意,您可能应该删除最后一个参数actualCallback()成员函数,因为这只是this指针,非静态成员函数不需要显式传递该指针。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++11 中的 C 风格回调 的相关文章

随机推荐

  • 如何在iPhone中实现VoIP+SIP? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想为 iPhone 开发 VoIP 应用程序 但我不知道 VoIP 概念的基础知识 也不知道是否有任
  • msbuild PackageReference.PrivateAssets = 全部似乎不起作用

    我有一个引用 NUnit3TestAdapter 的测试项目 我不会将此引用复制到依赖于此的项目 我认为设置 PrivateAssets All 就可以了 但显然我误解了它的工作原理 因为它没有达到预期的效果 这是代码 汇总 Rollup
  • Java中字符与int的转换

    您无法从 int 转换为 char 因此这是非法的int i 88 char c i 然而这是允许的char c 88 不是一个普通的数字并且int文字 这怎么被允许呢 char实际上是 Java 中的无符号 16 位整数类型 与其他整数类
  • 无法通过反射休眠获取字段值

    我在 jpa 中更新对象时遇到问题 我有 Bean 用户 public class User Id GeneratedValue strategy GenerationType IDENTITY Column name id unique
  • 访问Android的OBEX服务器并读取数据

    我想知道是否可以使用 Bluecove 从 Windows 的 Android OBEX 服务器读取数据 联系人 未接来电等 我在 Windows 中尝试了以下代码 但它返回OBEX HTTP NOT ACCEPTABLE连接时 据我所知
  • Marklogic 8 Windows 7 安装后登录

    我已在具有 8Gb 内存的 64 位 Windows 7 计算机上安装了 MarkLogic 8 服务器似乎运行良好 除了我无法登录之外 一切似乎都很好 使用 使用 Marklogic Server 或 管理 Marklogic Serve
  • UIAlertController:addSubview

    我想向我的警报控制器添加一个子视图 但为什么按钮要放在顶部呢 我该如何解决这个问题 let alert UIAlertController title nil message nil preferredStyle UIAlertContro
  • HTTP 错误 404.3 - 未找到 - 由于扩展配置,无法提供您请求的页面

    HTTP 错误 404 3 未找到 由于扩展配置的原因 无法提供您请求的页面 如果页面是脚本 请添加处理程序 如果应下载该文件 请添加 MIME 映射 IIS 7 上托管的 WCF 服务出现此错误的原因可能是什么 已回答here https
  • Groovy 文件无法在 Intellij IDEA 中编译

    我有 Maven 项目 包含 java 和 groovy 测试 在命令行maven编译中 所有测试都在运行 但在我的IDEA项目 由 AutoImport maven项目 自动创建 中 IDEA将groovy文件复制到 target tes
  • IE7 与 Firefox/Opera/Chrome 之间的间距差异

    我对 IE7 与 Firefox Chrome Opera 中无序列表的垂直空间量一直存在问题 而且我似乎找不到解决方案 在IE7中 空间变小了 这也是我希望看到的 在 Firefox Chrome 和 Opera 中 之间的间距大约是原来
  • java.lang.RuntimeException:在android中createWindowSurface失败EGL_BAD_ALLOC

    我为我的应用程序创建了 1080x1920 的自定义 Galaxy S4 AVD 我可以在该 AVD 中运行我的应用程序 几秒钟后它会闪烁并抛出一些像这样的错误 02 05 12 06 39 809 E EGL emulation 829
  • 将泛型参数转换为整数或从整数转换

    我想编写通用类 旨在与内置类型一起使用 例如byte and ushort 在内部计算中 我需要将泛型类型转换为整数 然后再转换回泛型类型 我找到了编译此类代码的方法 例如 class Test
  • 使用arm-linux-androideabi-4.4.3编译ICU

    我想使用 Cygwin 交叉编译 Android 的 ICU 静态库 到目前为止 我已经能够配置和制作 Cygwin MSVC 和 Cygwin 版本 我已经安装了android ndk r7 并且可以在toolchains目录中看到gcc
  • 为什么应该使用条件样式表?

    这个问题涵盖了大部分内容 但我试图向想要完全放弃条件样式表 IE6 移动设备等 的高级开发人员提出一个清晰的论点 请记住 我们实际上并没有消除 IE6 只是消除了样式表 还是我疯了 应该接受这个 还有什么选择呢 CSS 黑客 我有 IE7
  • 当用户点击下拉列表 HTML 选择标签时,ios8 iPad uiwebview 在显示弹出窗口时崩溃

    在 ios8 和 iPad 上 如果uiwebview正在显示一个包含下拉列表的 HTML 页面 例如这个页面http www w3schools com tags tryit asp filename tryhtml select htt
  • Maven War 插件中的过滤

    我不明白 Maven War 插件的以下过滤器配置 有人可以向我解释一下他们在做什么吗 我已经用第一个示例和第二个示例标记了代码
  • 如何对 ExecutorService 为任务生成新线程进行单元测试?

    使用 ExecutorService 时 一个单元如何测试是否为可运行任务生成了新线程 基本上 我的应用程序有一个静态线程池 public static final ExecutorService executorService Execu
  • 如何通过管道传输或重定向curl -v 的输出?

    由于某种原因 输出总是被打印到终端 无论我是否通过 2 gt 或 gt 或 重定向它 有办法解决这个问题吗 为什么会发生这种情况 add the s 静默 选项删除进度表 然后将 stderr 重定向到 stdout 以在与响应正文相同的
  • 始终并行运行恒定数量的子进程

    我想使用子进程让编写的脚本的 20 个实例并行运行 假设我有一个包含大约 100 000 个条目的大 URL 列表 并且我的程序应该控制我的脚本的 20 个实例始终在该列表上工作 我想将其编码如下 urllist url1 url2 url
  • C++11 中的 C 风格回调

    在 C 11 项目中 我使用需要 C 风格回调的 C 风格第三方库 在我的例子中为curl 为了实现这一点 我使用了 指向成员的指针 运算符 size t c callback wrapper char ptr size t size si