如何用C++写一个独立于平台的封装函数[重复]元程序设计

问题描述 投票:0回答:1

我使用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);
...
}
c++ c++11 c++14
1个回答
1
投票

我不会把它写成这样。

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",如果没有 % 格式字符串中的标记。


2
投票

您可以使用 vsnprintf_vsnprintf 而不是 snprintf_snprintf 分别在 WrapperSprintf. 这些函数使用变量参数列表。

参考文献。


0
投票

如何用C++写一个独立于平台的封装函数?

一种方法 是为了 读懂C++标准 (例如 n3337 为C++11),或者选择一个较新的标准。如C++17, 并坚持那里提到的功能.

另一种方法是在库上面写你的C++代码 诸如 QtPOCO提升GTKmm) 提供了一个高于所有你想针对的平台的抽象。

对于独立的C++代码 参编 然后在嵌入式平台上运行(例如,一些移植的 FreeNOSRaspBerry Pi 4,或最近的一些 安卓系统AutoSar)这可能是一个技术挑战。

请仔细阅读以下文件 你的 C++编译器

选择一个足够好的 建立自动化 工具(如 GNU make忍者 或其它)来运行你的C++编译器(以及其它程序,可能是你的元程序)。

也可以考虑为你的C++程序提供一个网络接口。

工具包如 重量Libonion 想到 cpp-httplib). 如今大多数桌面操作系统都有一些网络浏览器(如 火狐,本身用C++编码)。)

还可以考虑一些 元编程 办法。

编写你的小程序,生成C++代码,有助于移植性。

SWIG 启发 (另见以下例子) ANTLR 解析器生成器 Qt mocజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజజ RefPerSys 项目,该 FLTK 工具箱的灵感,或搜索 奎因 用C++编码的程序)。) 该 GPPGNU m4 预处理程序也可能是有用的。你的生成C++代码的元程序可能会被编码为 蟒蛇, 路亚, 诡计或者只是C++,等等。

所以,如果你的C++编译器中有相关的可移植性警告,请启用。对于 海湾合作委员会,改为 这个. 考虑使用一些静态分析器(如 Clang静态分析器Frama-C++覆盖率虫生 或者 俾斯蒙 到2020年底;见 本稿 报告)来帮助你。

记住这句老话

根本就没有 手提 代码,有的只是一些移植的软件......

归属忘了,但我在上个世纪看到过类似的东西。

© www.soinside.com 2019 - 2024. All rights reserved.