在 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);
我正在使用 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);