掌握C++ std::function 语法的问题

Problems grasping C++ std::function syntax

本文关键字:问题 语法 function std 掌握 C++      更新时间:2023-10-16

我在将消息从 DLL 的日志记录函数发送到客户端的日志记录函数时遇到问题。 我可以使用这样的函数指针:

.DLL:

class InnerLogger
{
public:
static std::function<void(const std::string& message, int level)> loggerCallback;
static std::stringstream logMsg;
static int logSend(LogLevel logLevel);
};
void setLoggingFunction(const std::function<void(const std::string& message, int level)>& logFunction)
{
InnerLogger::loggerCallback = logFunction;
}

客户:


void outerLogger(const std::string& message, int level)
{
// display/save messages
}
main()
{
std::function<void(const std::string& message, int level)> logFunctionPtr = outerLogger;
setLoggingFunction(logFunctionPtr);
}

我可以使用InnerLogger::logSend和outerLogger来获取它。

但是当"外部"记录器是类成员时,我做错了:

(DLL 保持不变(

客户:

class OuterLogger
{
public:
OuterLogger();
~OuterLogger();
void logFunction(const std::string& message, int level);
};
void OuterLogger::logFunction(const std::string& message, int level)
{
// display/save messages
}
main()
{
OuterLogger outerLogger;
std::function<void(const std::string& message, int level)> logFunctionPtr = outerLogger.logFunction;
setLoggingFunction(logFunctionPtr);
}

下面是如何将类绑定到函数的示例:

#include <iostream>
#include <functional>
class A {
public:
int x = 1;
void func() {
std::cout << x;
}
~A() {
x = 2; // just to test the destructor
}
};
int main()
{
std::function<void(void)> f;
{
A a;
f = std::bind(&A::func, a); // do not bind &a because it will be out of scope
}
f();
return 0;
}

在您的情况下,您可以使用:

std::function<void(const std::string& message, int level)> logFunctionPtr = std::bind(&OuterLogger::logFunction, outerLogger, std::placeholders::_1, std::placeholders::_2);

您可以使用 lambda 函数代替绑定:

std::function<void(const std::string&, int)> logFunctionPtr =
[outerLogger](const std::string& message, int level) mutable {
outerLogger.logFunction(message, level);
};

我尝试了几种不同的变体来传递函数指针,但没有一种有效,但事实证明该代码没有任何问题。

当我使用DLL记录器成功接受的任何形式的代码时,调试显示它之后会立即变为空。

我正在使用 VS 的测试资源管理器。事实证明,一些经过测试的流程实例没有正确关闭,所以我将测试主机进程卡在后台,我认为地址以某种方式变得混乱。

线索是间歇性地无法多次运行测试,以及在调试模式下非常奇怪的行为 - 执行标记向后跳跃并产生神秘的WINRT_ASSERT(!is_sta(((异常。答案是运行进程资源管理器并检查VS下卡住的进程。(有点烦人,VS无法告诉我它正在测试的过程有问题,但NVM(

我的代码使用 WinML 库。如果我在 CPU 模式下运行,那很好。如果我使用 GPU,它会卡在关机时,所以我需要找出原因。

谢谢大家的帮助。

编辑:我在问题中的最初假设是将代码从非对象移动到对象是一个问题 - 这是完全错误的。代码的原始非对象版本之所以有效,是因为它位于演示客户端中,这是一个调用 DLL 的单个可执行控制台程序,它从未受到狡猾的关闭问题的影响。在具有多个实例的单元测试套件中,它成为一个问题。