- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试转换一些代码,以便它也能在 gcc 上编译(现在,它只能在 MSVC 上编译)。
我遇到的代码是伪格式化函数,它接受格式字符串和零个或多个参数作为输入 (const char *format, ...
)。然后它将处理 一些 占位符消耗 一些 参数,并将其余部分与动态生成的新 va_list 一起传递给 vsprintf
。
这是生成新 va_list
的实际代码:
char *new_args = (char *) malloc(sum);
char *n = new_args;
for(int i = 0; i < nArgs; i++)
{
int j = order[i];
int len = _getlen(types[j]);
memcpy(n, args + cumulOffsets[j], len);
n += len;
}
vsprintf(buffer, sFormat.c_str(), new_args);
在我的辩护中,我没有也永远不会编写这段代码。事实上,我认为这是我一生中见过的最骇人听闻的事情之一。
但是,这个函数非常复杂,非常古老,而且非常重要。它也已经多年没有修改(好吧,除了现在)所以虽然我想从头开始重写它,但我无法证明它所花费的时间以及它会引入的错误。
所以,我需要一种方法在 GCC 上做同样的事情。但是 va_list
不是 char *
所以我得到:
error: ISO C++ forbids casting to an array type '__va_list_tag [1]'
最佳答案
我有点迷路了。为什么您需要一个新的动态生成的 va_list?为什么不重用旧的呢?
我相信 vsnprintf() 使用当前的 va_list 对象(如果你可以这样调用它的话)。所以你可以自由地 va_start(),通过 va_arg() 使用你想要的参数,然后通过 va_list 将剩余的参数传递给 < em>vsnprintf(),然后调用va_end()。
我错过了什么吗?为什么要深拷贝?
如果你确实需要一个深拷贝,为什么不用 va_start() 新鲜的,通过 va_arg() 删除你想要的参数,然后传递结果 va_list 对象到 vsnprintf()。
(每次调用 va_arg 都会修改 va_list 对象,以便下一次调用返回下一个参数。)
或者,您可以只使用 va_copy()。 (尽管一定要在它后面加上相应的 va_end()。)
附录:另请注意,这些 va_ 宏基于 C89 和 C99 标准。 GNU g++ 将支持它们。 Microsoft 的局限性更大一些。
跟进 TonyK 的评论:
如果您从 va_list 中拉出前 N 项,我上面所说的就有效。如果您要从中间拉出元素,那就更难了。
构造 va_list 没有可移植的方法。
但是,您可以将格式字符串分开,用它来确定对象类型( double 、 float 、整数等),然后用它自己的格式字符串(原始格式字符串的一部分)单独打印每个对象.多个 snprintf() 调用会导致一些开销。但是,如果不经常调用此例程,它应该是可行的。
您还可以使用适当制作的 va_list 打印出原始格式字符串的子部分。换句话说,第一个 vsnprintf() 调用打印元素 1..3,第二个元素 5..7,第三个 10..13,等等。(如 vsnprintf() 将忽略 va_list 上超出其需要的额外元素。您只需要一系列相应的格式字符串片段,并使用 va_list 弹出项目em>va_arg() 根据每次 vsnprintf() 调用的需要。)
关于c++ - 如何在 GCC 上创建 va_list?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4535050/
尝试编译此代码时 #include void bar_ptr(int n, va_list *pvl) { // do va_arg stuff here } void bar(int n,
假设我有一个函数,它接受可变参数 (...) 或从另一个此类函数传递的 va_list 。主要逻辑在这个函数本身(我们称之为 f1),但我想让它将 va_list 传递给另一个函数(我们称之为 f2)
看似简单的问题,但一直未能在 SO 或 C 标准中找到答案。问题是 va_list 是否必须是 C 中函数的最后一个参数(当然,假设该函数将 va_list 作为参数)。 例如,这样安全吗? int
我正在尝试打印字符串类型的参数变量,但我一直卡在这上面 想法 尝试使用 _Str[i] 作为 while 循环内的表达式在 srting 内部移动,一旦 _Str[i] == '\0' 返回 (-1
下面的 max 函数应该返回 5,但它返回的是 4294967294。我怀疑奇怪的行为是由变量转换引起的,但无法弄清楚。有人能检测出故障吗? 系统:Windows 7(64位),mingw64 #in
在 Fedora 11 上编译一些工作代码时,我收到此错误: /usr/include/c++/4.4.1/cstdarg:56: error: ‘::va_list’ has not been de
全部, 我想控制 va_list 中的传递参数的数量。 va_list args; va_start(args, fmts); vfprintf(stdout, fmts, args)
我有一个很好的 C++ 函数,它通过 va_list + va_start + va_arg 支持多个参数。但我必须将我的项目转换为 C。转换后,这个 va_list 构造被编译器拒绝(多个错误)。有
我已经编写了这段代码,但我不确定它是否可以。 size_t sendHeaders(int fd, int seconds, const char* header1, ...) { size_
我无法找到我的“问题”的答案。 我创建了一个函数,它接受不同数量的整数('findMinVal(int x, ...)')并返回所有调用中的最小数字。现在我的程序直接通过代码获取参数: int mai
我一直在追踪一个问题,并将范围缩小到这个框架: #include #include #include #include #include #include typedef struct _
我有一个主要更新,我在通话前进行访问控制。我想在我的代码中使用一个地方来调用任何紧急函数。 我有一个结构 ACTION: { FUNC_PROTOTYPE pfnAction; uns
我目前有 2 个函数重载: void log(const char* format, ...); void log(const string& message); 我希望在这个调用的情况下:log("
在 case 's' 下,我得到一个坏指针 (0xcccccccc) 异常: string Logger::format(const char *str, va_list args) { os
#include #include void s(const char* param, ...) { va_list arguments; va_start (arguments,
我试着写一个这样的函数: int solve(double* x, double xA, double xB, double zeps, double funct(double x
我有这样的代码 #include "atlstr.h" void DisplayMessage(CString pszFormat, ...) { CString str; va_l
我正尝试在 C++ 中为一个项目实现一种反射形式。这个想法是,您将带有标签的类作为一种模板注册到映射中,然后调用共享基类的 cloneNew 方法来实际创建您想要的对象。但是,当我尝试使用 va_li
我已经(简单地)编写了这段代码。但它需要两次修复才能确定。 size_t send_header(int fd, int seconds, const char* header1, ...) {
我有一个用于微 Controller 的以太网库(用于 lpc2478 的 keil rl-tcpnet)。库以这种方式在调试输出函数中使用 va_list(指向 stdarg.h 中定义的 arg
我是一名优秀的程序员,十分优秀!