gpt4 book ai didi

c++ - Windows FormatMessage 的安全/灵活外观

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:20:22 28 4
gpt4 key购买 nike

我需要使用 FormatMessage()对于一个项目,但我不喜欢它可怕的界面。有谁知道在允许替换参数的同时整理它的外观?

我刚刚阅读了 second part of the FastFormat introduction ,并且正在考虑为 FormatMessage() 编写一个扩展(或询问 FastFormat 项目团队,他们是否有一个在工作中),但我渴望尽快得到一些东西,所以如果还有其他合适的东西,我可能会捕获它。

我想要的是能够编写如下代码:

HINSTANCE netevent = ::LoadLibrary("netevent.dll");
std::string msg = LookupError(netevent, EVENT_SERVICE_START_FAILED_II,
"child-svr", "parent-svr", "ship happens");
::puts(msg.c_str());

这会给出结果:

The child-svr service depends on the parent-svr service which failed to start be cause of the following error:
ship happens

我构建的当前包装器具有以下接口(interface):

std::string LookupError(HINSTANCE hinst, DWORD id, ...);

这有两个问题:

  • 它不是类型安全的,因为它很容易传递任何类型 - intstd::stringvoid* - 也就是说不是 const char*
  • 参数的数量很容易与表示错误的格式字符串所需的数量不匹配

鉴于 FastFormat 的能力在类型安全方面,我想知道是否有一种方法可以遵循其机制来处理 FormatMessage() .

最佳答案

由于编译器无法检查要插入到格式字符串中的参数数量,因此不可能在编译时实现真正的类型安全。

您只需对不同数量的插入参数进行一些重载,然后使用诸如 boost::any 之类的灵活方式指定插入的值,即可完成大部分工作。所以两个参数的重载是:

std::string FormatMessage(HINSTANCE hinst, DWORD id, const boost::any &arg1, const boost::any &arg2);

当您从 arg1 检索值时,如果您尝试获取错误的类型,boost 将抛出异常,因此您只需要检查格式字符串并尝试从每个参数中获取所需的类型。

或者,您可以使用模板和 std::ostringstream(或 boost::lexical_cast)以获得非常灵活的版本;同样会有重载以允许参数数量变化,所以这里是单参数版本:

template <class TArg1>
std::string FormatMessage(HINSTANCE hinst, DWORD id, const TArg1 &arg1)
{
std::ostringstream arg1Stream;
arg1Stream << arg1;
std::string arg1String = arg1Stream.str();

DWORD_PTR argArray = reinterpret_cast<DWORD_PTR>(arg1String.c_str());

// ... etc
}

这样你就可以从每个参数中获取一个字符串,只要传递的类型可以被流式传输,并且只要格式字符串只需要插入字符串就不需要其他任何东西。

关于c++ - Windows FormatMessage 的安全/灵活外观,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/844395/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com