在 C++ 中使用回调

Using callbacks in C++

我正在使用 C++ 开发一个项目,但在应用程序的某个时刻它失败并生成核心转储。该应用程序使用了几个 classes,出于此处的目的,我将重点放在其中一个 classes 上,我将其称为 A,并将其实例化为对象 a。这有大量的成员函数,目前只有少数正在使用,但其中一个会生成日志以生成用于调试的诊断信息。我想用它来找出应用程序失败的原因。

该项目是将调用各种成员函数的代码放在一起,虽然我可以访问源代码和一些有限的文档,但可以更改 none 代码,所有更改都在使用 classes 并调用成员函数的代码。有问题的成员函数是:

void enable_log (log_callback callback, void * user_data = nullptr)

其中第一个参数回调包含消息,第二个参数是可选的。现在它可以设置为 nullptr,因此将被调用为:

a.enable_log(callback, nullptr);

根据该文档,完全不清楚回调到底是什么。但是,在查看源代码时,这是:

using log_callback = void (*)(const std::string& message, void* user_data);

在头文件中,其中 log_callback 是 const std::string& 的别名,如果我理解正确的话。

我已经在使用 Visual Studio 2019 的平台上拥有虚拟 classes 和一些测试成员函数来模拟在远程 Linux 服务器上调用成员函数,但我无法找到使用上述成员函数的方法。我将测试成员函数添加到虚拟 class 中,如下所示:

void enable_log(const std::string& callback, void* user_data = nullptr) {
    callback = "ABCD";
}

它应该生成一个返回的测试字符串,这样在实际应用程序中这个字符串将具有将被写入文件的诊断信息。但是,“=”是一个错误。

想法是在 main 函数中声明一个空字符串,然后 enable_log() 应该填充这个可以打印出来的字符串。

我花了一些时间查看各种资源,包括 Whosebug,但我找不到返回包含可打印信息的字符串的方法。我需要一个简单的方法来模拟这个,正如我上面所说的,我不能改变真正的成员函数的源代码,所以模拟的成员函数必须以同样的方式产生一个字符串。这是怎么做到的?一些建议将不胜感激。

回调,简单来说,就是稍后在某个时候调用的一些函数。示例:

void callback_fn(int a);

using callback_t = (void)(*)(int a);
void some_func(callback_t);

您可以像这样使用 some_func()

some_func(callback_fn);

完整示例在这里:https://godbolt.org/z/ET3GhfYrv

对于您的用例,回调的参数略有不同。阅读语法的方法如下:

using log_callback = // this just creates an alias for whatever is on the right handside

void // the return type of the "callable" should be void

(*) // this tells us that it is a function pointer

(const std::string& message, void* user_data) // These are the arguments the callable takes. It is a "std::string" and a "void *"

要使用它,只需创建一个具有相同签名的免费函数:

void callable(const std::string &msg, void *userData = nullptr)
{
   // msg is the data sent by the function. use it in whatever way
   // you want.
   std::cout << msg << '\n';
}

// Pass it to the enable_log
enable_log(callable);