C++ 通用回调实现

2024-03-17

我有一段代码,它以 XML 的形式从 flash 播放器获取消息,将它们解析为函数和参数,并调用该函数的已注册回调。 我想要替换的代码片段是做得很好(几乎)的通用回调机制:flashSDK 的通用回调实现代码 (ASInterface.inl) https://github.com/cpzhang/bud/blob/a37348b77fb2722c73d972a77827056b0b2344f6/trunk/tool/flash/ASInterface.inl#L393.

问题是这段代码是为闪存编写的,我想更换闪存并使用具有相同接口的其他服务。此回调机制是否有任何标准实现(std?boost?其他开源的东西?)?

此代码实现了通用回调机制,您可以在映射中使用参数数量和类型注册函数:

void SomethingHappened(int a, int b) {print a + b;}
void SomethingElseHappened(string abcd) {print abcd;}
callbacks["SomethingHappened"] = &SomethingHappened;
callbacks["SomethingElseHappened"] = &SomethingElseHappened;

然后搜索它并使用参数数组进行调用:

Callbacks::iterator itCallback = callbacks.find(functionName);
if (itCallback != callbacks.end())
{
    HRESULT result = itCallback->second.Call(arguments, returnValue);
}

完整用法示例:

//init callbacks
std::map<std::wstring, Callback> callbacks;
void SomethingHappened(int a, int b) {print a + b;}
void SomethingElseHappened(string abcd) {print abcd;}
callbacks[functionName] = &SomethingHappened;

void MessageArrived(string xmlInput)
{
    string functionName = parseFunctionName(xmlInput);
    Callbacks::iterator itCallback = callbacks.find(functionName);
    if (itCallback != callbacks.end())
    {
        //parse arguments
        std::vector<std::wstring> args;
        _Args::split(xml, args);
        ASValue::Array arguments;
        for (size_t i = 0, s = args.size(); i < s; ++i)
        {
            ASValue arg; arg.FromXML(args[i]);
            arguments.push_back(arg);
        }
        ASValue returnValue;
        //***this is where the magic happens: call the function***
        HRESULT result = itCallback->second.Call(arguments, returnValue);
        return result;
    }
}

你可能需要一个包装器std::function, 就像是:

template <typename T> struct Tag{};

// Convert ASValue to expected type,
// Possibly throw for invalid arguments.
bool Convert(Tag<Bool>, AsValue val) { return (Boolean)val; }
int Convert(Tag<int>, AsValue val) { return (Number)val; }
// ...

struct Callback
{
private:
    template <std::size_t ... Is, typename Ret, typename ... Ts>
    static Ret call_impl(Ret(* func)(Ts...), std::index_sequence<Is...>)
    {
        if (arr.size() != sizeof...(Is)) throw std::invalid_argument{};
        return func(Convert(tag<Ts>{}, arr[Is])...);
    }
public:
    template <typename Ret, typename ... Ts>
    Callback(Ret(* func)(Ts...)) : Call{[func](ASValue::Array arr, ASValue& ret)
        {
            try
            {
                ret = Callback::call_impl(func, std::make_index_sequence<sizeof(...(Ts)>());
                return S_OK;
            } catch (...) {
                return E_INVALIDARG;
            }
        }}
    {}

    std::function<HRESULT(ASValue::Array, ASValue&)> Call;
};

std::index_sequence是 C++14,但您可能会在 SO 上找到实现。

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

C++ 通用回调实现 的相关文章

  • 为什么 VB.NET 和 C# 中针对值检查 null 存在差异?

    In VB NET http en wikipedia org wiki Visual Basic NET有时候是这样的 Dim x As System Nullable Of Decimal Nothing Dim y As System
  • 获取 std::variant 当前持有的 typeid(如 boost::variant type())

    我已经从 boost variant 迁移到 std variant 但遇到了障碍 我在 boost type 中使用了一个很好的函数 它可以让你获取当前持有的 typeid 看https www boost org doc libs 1
  • 如何在编译C代码时禁用警告?

    我正在使用 32 位 Fedora 14 系统 我正在使用编译我的源代码gcc 有谁知道如何在编译c代码时禁用警告 EDIT 是的 我知道 最好的办法是修复这些警告以避免任何未定义 未知的行为 但目前在这里 我第一次编写了巨大的代码 并且在
  • 导出类时编译器错误

    我正在使用 Visual Studio 2013 但遇到了一个奇怪的问题 当我导出一个类时 它会抛出 尝试引用已删除的函数 错误 但是 当该类未导出时 它的行为会正确 让我举个例子 class Foo note the export cla
  • 是否有像 gccxml 这样的用于生成包装器的 C 标头解析器工具?

    我需要为一种新的编程语言编写一些 C 标头包装器 并且想要类似 gccxml 的东西 但不完全依赖 gcc 以及它在 Windows 系统上带来的问题 只需要读C而不是C 只要有完整的文档记录 任何格式的输出都可以 Linux Solari
  • 序列化和反序列化 Visual Studio 解决方案文件 - 或以编程方式编辑?

    我想以编程方式添加和删除项目 解决方案文件夹和其他项目 例如解决方案的资源文件 但我不确定最好的方法是什么 对于那些不知道的人 高度简化 解决方案文件 sln 通常如下所示 Microsoft Visual Studio Solution
  • 指向字节数组的指针

    由于 Misra C 的要求 我的一位同事想要使用指针声明 但我遇到了一些问题 Misra 安全关键指南 不会让我们纯粹的程序员使用指针 但会让我们对数组字节进行操作 他打算获取一个指向字节数组的指针 因此我们不会在堆栈上传递实际的数组 T
  • 您可以在一个 Windows Azure 实例上部署多个 Web 应用程序吗?

    是否可以在一个 windows azure 小型计算实例中运行一堆 Web 应用程序 我正在考虑使用 Azure 作为放置一堆处于开发和非生产状态的项目 Web 应用程序 的地方 有些实际上已经被封存了 但我想在某个地方有一个活跃的实例 我
  • 以编程方式更新 ClickOnce 应用程序的部署清单会导致缺少 4.0 中所需的 <兼容框架> 元素

    我正在致力于自动化 NET 4 0 ClickOnce WPF 应用程序的安装程序 该应用程序需要在应用程序配置文件 我经历了寻找必须遵循的具体步骤的棘手过程Mage exe http msdn microsoft com en us li
  • C#中Enum中定义的value__是什么

    What value 可能在这里 value MSN ICQ YahooChat GoogleTalk 我运行的代码很简单 namespace EnumReflection enum Messengers MSN ICQ YahooChat
  • dropdownlist DataTextField 由属性组成?

    有没有一种方法可以通过 C 使 asp net 中的下拉列表的 datatextfield 属性由对象的多个属性组成 public class MyObject public int Id get set public string Nam
  • 在VisualStudio DTE中,如何获取ActiveDocument的内容?

    我正在 VisualStudio 中编写脚本 并尝试获取当前 ActiveDocument 的内容 这是我当前的解决方案 var visualStudio new API VisualStudio 2010 var vsDTE visual
  • 使用 foreach 循环和 XmlNodeList C# 将新节点附加到节点列表

    目前我处理的是这样的XML类型 XML FILE http 20drive google com open id 0By5BxgNi9eGcRldxcEZNU0FDTzQ 参考XML文件 我想检查一个节点 如果找不到该节点 我必须将该节点附
  • 如何使用收益返回和递归获得字母的每个组合?

    我有几个像这样的字符串列表 可能有几十个列表 1 A B C 2 1 2 3 3 D E F 这三个仅作为示例 用户可以从几十个具有不同数量元素的类似列表中进行选择 再举个例子 这对于用户来说也是一个完全有效的选择 25 empty 4 1
  • 从 C 线程调用 Python 代码

    我对从 C 或 C 线程调用 Python 代码时如何确保线程安全感到非常困惑 The Python 文档 http docs python org c api init html non python created threads似乎是
  • ASP.NET Core Razor Page 多路径路由

    我正在使用 ASP NET Core 2 0 Razor Pages 不是 MVC 构建系统 但在为页面添加多个路由时遇到问题 例如 所有页面都应该能够通过 abc com language 访问segment shop mypage 或
  • 在 C++ 和 Windows 中使用 XmlRpc

    我需要在 Windows 平台上使用 C 中的 XmlRpc 尽管我的朋友向我保证 XmlRpc 是一种 广泛可用的标准技术 但可用的库并不多 事实上 我只找到一个库可以在 Windows 上执行此操作 另外一个库声称 您必须做很多工作才能
  • g++ C++0x 枚举类编译器警告

    我一直在将可怕的 C 类型安全伪枚举重构为新的 C 0x 类型安全枚举 因为它们是way更具可读性 不管怎样 我在导出的类中使用它们 所以我明确地将它们标记为导出 enum class attribute visibility defaul
  • C# 粘贴到文本框时检查剪贴板中的字符

    有没有一些方法可以在粘贴到文本框 C 之前仅检查剪贴板中的字符 Ctrl V 和右键单击 gt 粘贴 但不使用 MaskedTextbox 在文本框文本更改中添加规则以仅接受数字 例如 private string value privat
  • c# 模拟 IFormFile CopyToAsync() 方法

    我正在对一个异步函数进行单元测试 该函数将 IFormFile 列表转换为我自己的任意数据库文件类列表 将文件数据转换为字节数组的方法是 internal async Task

随机推荐

  • Python unittest:如何临时将标准输出消息重定向到缓冲区并测试其内容?

    我想捕获发送到的消息stdout our stderr 在测试期间暂时断言这些消息中是否出现某些字符串模式 import unittest class SomeTest unittest TestCase def test stdout s
  • Tomcat 6 堆大小 - 这是正确的吗?

    我在 Red Hat 机器上运行多个 tomcat 我想为每个 tomcat 配置单独的堆大小 某些实例使用更多内存 我可以在 catalina sh 文件中输入以下内容来设置堆大小最小 最大 bt CATALINA OPTS Xms64m
  • WPF 将控件可见性绑定到另一个控件的聚焦属性

    我有一个显示项目列表的组合框 我想在它旁边放置一个按钮来触发命令以查看所选项目的详细信息 到目前为止 一切都很好 现在我希望该按钮仅在组合框具有焦点时才可见 或处于 编辑 模式 但不仅在弹出窗口打开时 我想我可以将按钮的可见性绑定到组合框的
  • 命令“git checkout”的含义。 [复制]

    这个问题在这里已经有答案了 虽然我知道标题中的命令类似于撤消对当前存储库的更改 但我无法理解它的实际工作原理或如何读取该命令 任何线索都会有很大的帮助 git 结账
  • Python 中的参数解析(必需与可选)

    我目前正在编写一个能够采用多个标志的脚本 我希望它无论最后一个参数是什么都应该是 start stop status usr bin env python from argparse import ArgumentParser def ar
  • Oracle 11g - FOR 循环仅将工作日插入表中?

    我想将一些数据插入与明年日期相关的表中 实际上我只需要插入工作日 BEGIN FOR i IN 1 365 LOOP INSERT INTO MY TABLE ID MY DATE VALUES i to date sysdate DD M
  • 如何以Python方式获取numpy argwhere函数的最大值

    我想使用 numpy argwhere 来查找数据中的最大值在哪里 下面是一个示例集 描述了我正在做的事情 bins np arange 10 data np array 6 4 8 5 np argwhere bins
  • 有没有办法加快 python 中处理大型 CSV 和数据帧的速度?

    我正在处理一些大小在 1Gb 到 2Gb 范围内的 CSV 文件 仅将文件加载到 pandas 数据帧中就需要 20 30 分钟 而我执行的每个操作则需要 20 30 分钟 例如按列名称过滤数据帧 打印 dataframe head 等 有
  • Hibernate从数据库生成ID函数

    我的代码是 Id GenericGenerator name generator strategy increment GeneratedValue generator generator Column name PM ID nullabl
  • 我可以将 struts.xml 文件更改为其他文件吗?

    当我研究 struts2 时 我遇到了一个典型的问题 问题是我可以改名字吗struts xml文件到其他东西并使其工作 您可以使用您的web xml
  • 在 Windows 7 32 位 SP1 上安装 Python 3.8

    我无法在 Windows 7 32 位 SP1 上安装 Python 3 8 错误日志显示detected windows 7 sp1 without kb2533625我一整天都在搜索这个更新 但没有找到任何帮助 我认为这是 Python
  • “沟通”扩展中的内容js和后台js文件

    我正在编写扩展程序 遇到一个问题 我无法将数据从扩展程序菜单发送到content js 在扩展菜单中 我有一些直觉 填写并单击按钮后 我写下它们的值 我想将它们发送到content js该数据将用于实施html但由于某种原因 数据没有发送
  • Ansible 将变量传递给角色

    我想根据环境和主机名创建文件夹 用户和组 我的剧本将环境和主机名传递给角色 该角色应该从 defaults main yml 文件中选择正确的数据 剧本 roles role myrole environment xxx hostname
  • cakephp 如何将 bootstrap 框架 css 样式包含到我的应用程序中?

    有人将 cake php 与 bootstrap 框架 css 风格集成在一起吗 我希望能够在 cakephp 视图中使用 bootstrap 的优点 像 btn 和面板引导样式 https i stack imgur com dnQyD
  • Visual Studio Community 2017 中的条件参考

    我正在创建一个多平台应用程序 我有一个多目标共享库 针对 netstandard 2 0 和 net 4 5 请参阅项目文件
  • 自动映射器合并对象问题

    让自动映射器工作后 上一个问题 https stackoverflow com questions 36602430 automapper complex types mapping exception 我正在解决另一个问题 把它带到另一个
  • isNaN(1) 和 isNaN("1") 返回 false

    为什么在我下面的截图中isNaN 1 and isNaN 1 回报false 由于其中之一是数字 其中之一是字符串 因此 isNaN 1 应该返回 true From MDN https developer mozilla org en U
  • 如何跨架构使用 python-poetry?

    我的主要开发机器是x86 64虽然我的一些部署环境是arm7vl 树莓派 对于大多数 Python 开发来说 这不是问题 但某些 Python 库只能在PyPI https pypi org for x86 64 or piwheels h
  • 适用于 Linux 的与语言无关的正确制表符代码编辑器?

    我需要一个 Linux 文本编辑器来替换 Textpad 4 7 3 一个 Windows nagware 应用程序 但我尝试过的所有替代方案要么臃肿要么不完整 以下是我认为最重要的功能 按降序排列 正则表达式搜索 标记和替换 甚至跨所有打
  • C++ 通用回调实现

    我有一段代码 它以 XML 的形式从 flash 播放器获取消息 将它们解析为函数和参数 并调用该函数的已注册回调 我想要替换的代码片段是做得很好 几乎 的通用回调机制 flashSDK 的通用回调实现代码 ASInterface inl