gpt4 book ai didi

C++ "Dynamic"C 回调函数的函数指针

转载 作者:行者123 更新时间:2023-12-01 14:05:25 24 4
gpt4 key购买 nike

我有一个用于管理相机配置的 API。有 344 个单独的选项需要管理。当某个值发生变化时,API 会调用回调函数来通知程序。注册函数需要一个
void RegisterCallback(Option * ptr, void (fn*)(void*))
函数指针作为回调函数。 我不能使用单个函数进行回调,因为我现在做的回调来自 .

一种解决方案是创建 344 个单独的回调函数:

void callback0(void*);
void callback1(void*);
...
void callback{n-1}(void*);

static void(*)(void*) callbacks[] = {callback0, callback1, ..., callback{n-1}};

对于此解决方案,我需要使用单独的工具/脚本生成 header 。

另一种解决方案是使用一些预处理器魔法(BoostPP),比如
BOOST_PP_FOR((0,1024), PRED, OP, MYSTERIOUS_CALLBACK_MACRO);

根据我的经验,这些宏对于开发人员来说是不可读的,并且难以维护。

理想情况下,我可以使用类似的东西 RegisterCallback(popt, [n](void*){/*n-th callback*/});
但是 lambda 函数是一个仿函数而不是函数指针。

我的问题是:我可以动态创建这些函数吗?或者有没有比上面两个更好的解决方案?

谢谢你。

编辑

我从 Botje 那里得到了答案。将对象传递给函数回调需要您访问二进制级别的代码(超出 C/C++ 级别)。如果您可以允许,那么 libffi 可以是一个解决方案,因为它会生成一个指向您的函数的每个实例的特定指针。它得到了广泛的支持,但是,例如 Visual Studio Compiler 不在列表中。

编辑 2
正如其他人指出的那样,它也应该与 VS 一起使用。

最佳答案

您可以使用 libffi 动态生成闭包.这些是常规函数指针,可以保留一个指向用户数据的指针,在这种情况下是回调编号。

#include <iostream>
#include <vector>
#include "ffi.h"

using namespace std;
void the_callback(size_t num, void* arg) {
cout << "This is callback #" << num << " with argument " << hex << arg << endl;
}

void generic_cb(ffi_cif *cif, void *ret, void **args, void *user_data) {
the_callback((size_t) user_data, *(void **)args[0]);
}

typedef void (*Callback)(void*);

ffi_cif callback_cif;
int main() {
ffi_type *argtypes[] = { &ffi_type_pointer };
ffi_status st = ffi_prep_cif(&callback_cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, argtypes);

std::vector<Callback> callbacks;
for (size_t i = 0; i < 100; i++) {
void *cb;
ffi_closure *writable = (ffi_closure*)ffi_closure_alloc(sizeof(ffi_closure), &cb);
st = ffi_prep_closure_loc(writable, &callback_cif, generic_cb, (void*)i, cb);
callbacks.push_back((Callback)cb);
}

callbacks[13]((void*)0xabcdef);
callbacks[87]((void*)0x1234);
}

这会产生以下输出:
This is callback #13 with argument 0xabcdef
This is callback #57 with argument 0x1234

关于C++ "Dynamic"C 回调函数的函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60719322/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com