use*_*055 5 c++ lambda function-pointers functor
我有一个用于管理相机配置的 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}};
Run Code Online (Sandbox Code Playgroud)
对于此解决方案,我需要使用单独的工具/脚本生成标头。
另一种解决方案是使用一些预处理器魔法(BoostPP),比如
BOOST_PP_FOR((0,1024), PRED, OP, MYSTERIOUS_CALLBACK_MACRO);
Run Code Online (Sandbox Code Playgroud)
根据我的经验,这些宏对于开发人员来说是不可读的,并且难以维护。
理想情况下,我可以使用类似的东西
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);
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
This is callback #13 with argument 0xabcdef
This is callback #57 with argument 0x1234
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
541 次 |
| 最近记录: |