如何将 std::function 回调传递给需要函数指针类型定义的函数
How to pass a std::function callback to a function requiring a typedef of a pointer to a function
我有一个 C 库,它使用函数指针来注册命令。我想在我的 C++ 应用程序中使用它。我尝试结合使用 std::function 和 std::bind 来创建一个 C 兼容的函数指针,它将在 class 中调用我的成员函数。尝试通过 std::function 时出现编译错误。
// The way the C library typedef's the function
typedef int (*console_cmd_func_t)(int argc, char **argv);
// Function to register the callback needs a struct
struct {
console_cmd_func_t func;
} console_cmd_t;
void console_cmd_register(const console_cmd_t *cmd) {
// Register the command
}
// In my C++ class
typedef std::function<int(int argc, char **argv)> ConsoleFunction;
ConsoleFunction fn = std::bind(&MyClass::consoleCommandHandler, this, std::placeholders::_1, std::placeholders::_2);
const esp_console_cmd_t runCommand = {
.func = fn
};
console_cmd_register(&runCommand);
但是,这会导致以下错误:
cannot convert 'ConsoleFunction' {aka 'std::function<int(int, char**)>'} to 'console_cmd_func_t' {aka 'int (*)(int, char**)'} in initialization
显然不是同一个定义。但是,如果我尝试更正:
typedef std::function<console_cmd_func_t> ConsoleFunction;
我收到以下错误:
variable 'ConsoleFunction fn' has initializer but incomplete type
如何才能成功注册命令?
struct {
console_cmd_func_t func;
} console_cmd_t;
void console_cmd_register(const console_cmd_t *cmd) {
// Register the command
}
你的 C 程序是 ill-formed。我将假设 console_cmd_t
实际上不是引用代码中描述的未命名结构的实例,而是一个 typedef 名称:
typedef struct {
console_cmd_func_t func;
} console_cmd_t;
How can I successfully register the command?
通过使用函数期望的类型。他们不希望 std::function
,因此您可能不会使用 std::function
。也无法注册 non-static 成员函数,也无法注册捕获 lambda。
一个工作示例(假设进行了上述更正):
int my_callback(int, char **);
console_cmd_t my_struct {
.func = my_callback,
};
console_cmd_register(&my_struct);
为了调用 non-static 成员函数,您通常会将指向 class 的指针作为参数传递给回调。如果 C API 不允许传递用户定义的参数,那么唯一的选择就是使用全局状态。示例:
static MyClass gobal_instance{};
int my_callback(int argc, char **argv)
{
gobal_instance.consoleCommandHandler(argc, argv);
}
要避免全局状态,您需要re-design C 库。
我有一个 C 库,它使用函数指针来注册命令。我想在我的 C++ 应用程序中使用它。我尝试结合使用 std::function 和 std::bind 来创建一个 C 兼容的函数指针,它将在 class 中调用我的成员函数。尝试通过 std::function 时出现编译错误。
// The way the C library typedef's the function
typedef int (*console_cmd_func_t)(int argc, char **argv);
// Function to register the callback needs a struct
struct {
console_cmd_func_t func;
} console_cmd_t;
void console_cmd_register(const console_cmd_t *cmd) {
// Register the command
}
// In my C++ class
typedef std::function<int(int argc, char **argv)> ConsoleFunction;
ConsoleFunction fn = std::bind(&MyClass::consoleCommandHandler, this, std::placeholders::_1, std::placeholders::_2);
const esp_console_cmd_t runCommand = {
.func = fn
};
console_cmd_register(&runCommand);
但是,这会导致以下错误:
cannot convert 'ConsoleFunction' {aka 'std::function<int(int, char**)>'} to 'console_cmd_func_t' {aka 'int (*)(int, char**)'} in initialization
显然不是同一个定义。但是,如果我尝试更正:
typedef std::function<console_cmd_func_t> ConsoleFunction;
我收到以下错误:
variable 'ConsoleFunction fn' has initializer but incomplete type
如何才能成功注册命令?
struct { console_cmd_func_t func; } console_cmd_t; void console_cmd_register(const console_cmd_t *cmd) { // Register the command }
你的 C 程序是 ill-formed。我将假设 console_cmd_t
实际上不是引用代码中描述的未命名结构的实例,而是一个 typedef 名称:
typedef struct {
console_cmd_func_t func;
} console_cmd_t;
How can I successfully register the command?
通过使用函数期望的类型。他们不希望 std::function
,因此您可能不会使用 std::function
。也无法注册 non-static 成员函数,也无法注册捕获 lambda。
一个工作示例(假设进行了上述更正):
int my_callback(int, char **);
console_cmd_t my_struct {
.func = my_callback,
};
console_cmd_register(&my_struct);
为了调用 non-static 成员函数,您通常会将指向 class 的指针作为参数传递给回调。如果 C API 不允许传递用户定义的参数,那么唯一的选择就是使用全局状态。示例:
static MyClass gobal_instance{};
int my_callback(int argc, char **argv)
{
gobal_instance.consoleCommandHandler(argc, argv);
}
要避免全局状态,您需要re-design C 库。