我使用Snprintf将输出发送到缓冲区。使用C++ 11和桌面应用程序。
到目前为止,我只在windows平台上使用。但从现在开始,它必须支持不同的平台(Windows,Linux和Mac)。
为了支持多平台,我打算写一个带有#if标签的包装函数。
但我面临的挑战是,当从项目的不同地方调用WrapperSprintf时,参数的数量是不同的。
如何写一个通用的封装函数,可以在不同的地方使用不同的参数传递给WrapperSprintf函数?
我尝试了如下图所示的封装函数。请帮助我如何处理这个问题。
void WrapperSprintf( char buffer, const char *format, ... )
{
#if defined(_WIN32)
_snprintf_s(buffer, sizeof(buffer), format,...);
#else
snprintf(buffer, sizeof(buffer), format, ...);
#endif
}
调用WrapperSprintf函数1。
char m_systemTime[20];
char* CUPSManager ::getSystemTime()
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
WrapperSprintf(m_systemTime,"%d-%d-%d :%d:%d:%d" , timeinfo ->tm_year +1900,
timeinfo ->tm_mon +1,
timeinfo->tm_mday,
timeinfo->tm_hour,
timeinfo->tm_min,
timeinfo->tm_sec);
return m_systemTime;
}
调用WrapperSprintf函数2:
void getDevicePath()
{
wstring strDevPath;
strDevPath = (LPCWSTR)cDevicePath;
char cDevPath[2048];
WrapperSprintf(cDevPath,"%ls", strDevPath.c_str());
int nPathLength = strlen(cDevPath);
...
}
我不会把它写成这样。
void WrapperSprintf( char buffer, const char *format, ... )
{
#if defined(_WIN32)
_snprintf_s(buffer, sizeof(buffer), format,...);
#else
snprintf(buffer, sizeof(buffer), format, ...);
#endif
}
你在这里不需要一个功能。你需要的是选择正确的函数。宁可这样做。
#if defined(_WIN32)
#define WrapperSprintf _snprintf_s
#else
#define WrapperSprintf snprintf
#endif
如果你想变得更复杂,并有能力重新排列argumetns 那么我们可以更进一步。
#if defined(_WIN32)
#define WrapperSprintf(buffer, size, ...) _snprintf_s(buffer, size, __VA_ARGS__)
#elif defined(_WIERDYSTEM)
#define WrapperSprintf(buffer, size, ...) wierdsnprintf(size, buffer, __VA_ARGS__)
#else
#define WrapperSprintf(buffer, size, ...) snprintf(buffer, size, __VA_ARGS__)
#endif
注意: __VA_ARGS__
必须至少匹配一个参数(即不能匹配零)。所以用if来表示 "format和format-arguments",因为有可能有零个 "format-arguments",如果没有 %
格式字符串中的标记。
您可以使用 vsnprintf
和 _vsnprintf
而不是 snprintf
和 _snprintf
分别在 WrapperSprintf
. 这些函数使用变量参数列表。
参考文献。
如何用C++写一个独立于平台的封装函数?
一种方法 是为了 读懂C++标准 (例如 n3337 为C++11),或者选择一个较新的标准。如C++17, 并坚持那里提到的功能.
另一种方法是在库上面写你的C++代码 诸如 Qt 或 POCO 或 提升 或 GTKmm) 提供了一个高于所有你想针对的平台的抽象。
对于独立的C++代码 参编 然后在嵌入式平台上运行(例如,一些移植的 FreeNOS 到 RaspBerry Pi 4,或最近的一些 安卓系统或 AutoSar)这可能是一个技术挑战。
选择一个足够好的 建立自动化 工具(如 GNU make 或 忍者 或其它)来运行你的C++编译器(以及其它程序,可能是你的元程序)。
工具包如 重量 或 Libonion 想到 cpp-httplib). 如今大多数桌面操作系统都有一些网络浏览器(如 火狐,本身用C++编码)。)
的 SWIG 启发 (另见以下例子) ANTLR 解析器生成器 Qt mocజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ RefPerSys 项目,该 FLTK 工具箱的灵感,或搜索 奎因 用C++编码的程序)。) 该 GPP 或 GNU m4 预处理程序也可能是有用的。你的生成C++代码的元程序可能会被编码为 蟒蛇, 路亚, 诡计或者只是C++,等等。
所以,如果你的C++编译器中有相关的可移植性警告,请启用。对于 海湾合作委员会,改为 这个. 考虑使用一些静态分析器(如 Clang静态分析器或 Frama-C++或 覆盖率或 虫生 或者 俾斯蒙 到2020年底;见 本稿 报告)来帮助你。
记住这句老话
归属忘了,但我在上个世纪看到过类似的东西。