如何将 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 库。