以下代码在Windows上运行时C++工作:
void* paramsList[MAX_PARAMS_NUM] = { 0 };
...some code to populate paramsList (p.s MAX_PARAMS_NUM is a constant)
vsnprintf((char*)pStr, MAXLEN, (char*)pTempFormat, (va_list)paramsList);
这段代码在 Windows 上运行正常,但我试图让它在 Linux 上运行并且程序崩溃了,因为paramsList
到va_list
的这种转换在那里不起作用。
现在,此方案的设置是我从不受控制的服务器获取格式字符串。格式字符串('pTempFormat'(就像printf中使用的格式字符串,其中%的未知数量(最大值为MAX_PARAMS_NUM
(,我相应地填充参数列表,然后我使用vsnprintf
从我得到的格式字符串和参数列表中填充的值创建一个字符串。(根据从服务器接收的格式字符串,这些值可以是从整数到十六进制到字符*(又名字符串(以及它们的任意组合。
我不知道paramsList
传递给vsnprintf
多少个位置,直到我根据从服务器收到的格式字符串完成填充它。所以我需要以某种方式将可变数量的位置从paramsList
传递到vsnprintf
,或者将这些位置转换为va_list(我无法从我在网上阅读的内容中弄清楚该怎么做(。
我还考虑使用可变参数模板和va_list的组合 - 以某种方式将可变数量的位置从paramsList
传递到可变参数函数并将它们传递给vsnprintf
。但是我也无法弄清楚如何将某些位置从给定数组传递到可变参数函数。
更新:
我使用 Visual Studio 2015 在 Windows 上编译,使用 GCC 4.9 在 Ubuntu 上编译。
尝试在 Linux 上编译此代码时我遇到的错误是:error: ISO C++ forbids casting to an array type 'va_list {aka __va_list_tag [1]}'
va_list
是未指定的类型。这意味着它可能是一个void* []
或其他完全不同的东西。
它在某些情况下偶然工作只是va_list
与一个编译器在一个特定平台上的void* []
兼容,这绝不表明这是合法的。
不幸的是,处理此问题的正确方法是停止使用printf
系列并自己解析格式字符串,没有标准功能可以访问并获取解析后的格式字符串供您自己使用。