You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++模块中向SpdLog转发可变参数的问题求助

问题:C++模块封装SpdLog的可变参数转发与DLL导出问题

场景与需求

  • 项目基于C++模块开发,用Meyers单例模式封装SpdLog日志库,目标是将SpdLog完全隐藏在Core共享库内,未来可替换日志库而无需修改客户端代码
  • 客户端只需导入Logger模块即可调用日志接口,Core库静态链接SpdLog

期望客户端调用方式

import Logger;

int main()
{
    //调用单例封装类的静态方法
    Logger::Info("{1} is a {0}", "test", "This");
}

直接调用SpdLog验证正常

直接调用SpdLog实例的info方法可正常运行:

directSpdlogInstance->info("{1} is a {0}", "test", "This");

SpdLog的info方法签名:

template <typename... Args>
inline void info(format_string_t<Args...> fmt, Args &&...args);

尝试的实现方案及错误

方案1:无约束参数转发

实现代码:

template<typename...Args>
void Logger::Info(Args&&... args)
{
    //GetInstance()获取SpdLog实例
    GetInstance()->info(std::forward<Args>(args)...);
}

编译错误C7595:

'fmt::v9::basic_format_string<char,const char
(&)[32]>::basic_format_string': call to immediate function is not a
constant expression Nano C:\Dev\Nano\Projects\Core\src\Logger.cppm 30

方案2:启用SPDLOG_USE_STD_FORMAT后使用make_format_args

定义SPDLOG_USE_STD_FORMAT切换到标准库format,实现代码:

template<typename...Args>
void Logger::Info(std::format_string<Args...> fmt, Args&&... args)
{
    GetInstance()->info(fmt, std::make_format_args(args...));
}

编译错误C2664:

'void spdlog::logger::info<std::_Format_arg_store<_Context,const char
(&)[32]>>(std::basic_format_string<char,std::_Format_arg_store<_Context,const char (&)[32]>>,std::_Format_arg_store<_Context,const char (&)[32]>
&&)': cannot convert argument 1 from
'std::basic_format_string<char,const char (&)[32]>' to
'std::basic_format_string<char,std::_Format_arg_store<_Context,const
char (&)[32]>>'
with
[
_Context=std::format_context
] Nano C:\Dev\Nano\Projects\Core\src\Logger.cppm 34

方案3:启用SPDLOG_USE_STD_FORMAT后直接转发参数

修改实现为直接转发参数:

template<typename...Args>
void Logger::Info(std::format_string<Args...> fmt, Args&&... args)
{
    GetInstance()->info(fmt, std::forward<Args>(args)...);
}

问题:模块编译成功,但调用该模块的控制台项目出现链接错误LNK1104:

cannot open file 'C:\Dev\Nano\bin\windows-Debug\Core\Core.lib'

Core.dll已生成,但无对应的lib文件,通常此情况表示DLL无导出内容。但已通过NN_API(即__declspec(dllexport))导出静态模板方法:

export class Logger
{
public:
    Logger(const Logger& other) = delete;

    template<typename...Args>
    NN_API static void Info(std::format_string<Args...> fmt, Args&&... args);
...
}

客户端main函数已按预期调用该方法,需解决当前链接问题及之前的参数转发错误。

内容的提问来源于stack exchange,提问作者Todd Burch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 19:16:27