【问题标题】:How to use va_list correctly in a sequence of wrapper functions calls?如何在一系列包装函数调用中正确使用 va_list?
【发布时间】:2014-05-15 11:07:12
【问题描述】:

我有一个用于微控制器的以太网库(用于 lpc2478 的 keil rl-tcpnet)。 库以这种方式在调试输出函数中使用 va_list(指向 stdarg.h 中定义的 arg 数组宏的标准指针):

void __debug__ (const char *fmt, ...)
{
  va_list args;
  va_start (args,fmt);
  vprintf (fmt,args);
  va_end (args);
}

但是 vprintf 将数据发送到不正确的流,我需要将库的调试输出重定向到正确的串行端口。 库有 .c cofigure 文件,我编写 c++ 代码,所以我使用包装函数指针从 c 代码调用 c++ 样式代码。所以我重写了这个函数:

extern void (* printDebugMsg)(const char * fmt, ...);    
void __debug__ (const char *fmt, ...)
{
  va_list args;
  printDebugMsg(fmt, args);
}

其他cpp文件:

void printDebugMsgImplementation(const char * fmt, ...)
{
  va_list args;

  char buffer[100] = { 0 };

  sprintf(buffer, fmt, args);

  debugUart->write(buffer);
}
void (* printDebugMsg)(const char * fmt, ...) = &printDebugMsgImplementation;

结果调试输出如下:

TCP: Init 0 Sockets
IP :  Src. IP : 0.0.14.1668436768
ETH:  Dest.MAC: A1E05E10:A0002B44:5F9F:01:5FF8:33

文本和一些数字(如 0)似乎是正确的,但大多数其他数字似乎格式错误(但也可能是内部库问题)。 我尝试使用 va_list 重写我的代码,因为它通常在示例中进行:

void __debug__ (const char *fmt, ...)
{
  va_list args;
  va_start (args,fmt);
  printDebugMsg(fmt, args);
  va_end (args);
}

和.cpp文件:

void printDebugMsgImplementation(const char * fmt, ...)
{
  va_list args;

  char buffer[100] = { 0 };

  va_start(args, fmt);
  vsprintf(buffer, fmt, args);
  va_end(args);

  debugUart->write(buffer);
}

但是结果肯定比原来更糟:

TCP: Init -1579131344 Sockets
ARP:  Dest.IP: -1579131400.-1610601474.24805.4
ARP:  Src.MAC: A1E05DF8:A0002BFE:60FF:04:616C:20

我做错了什么?在我的包装函数调用的情况下如何处理 va_list?

【问题讨论】:

  • 次要:带有双下划线的名称保留用于实现使用,因此请为您的函数调用其他名称以避免与标准标题中的内容可能发生冲突
  • 我从不使用带有双下划线的函数。这是我无法更改签名的库函数。联系基尔。 :)

标签: c++ c embedded


【解决方案1】:

您不能将va_list 传递给期望... 的函数,除非该函数(当然)在变量参数部分期望va_list。您的代码显然没有。

您需要在printDebugMsg() 中明确接受va_list 参数,因为这就是您要传递的内容。参见例如vprintf(),它为printf() 家族解决了这个问题。

【讨论】:

  • 您说的非常对,谢谢!我在包装函数中将 <...> 更改为 va_list 并在其中删除了 va_list start/end 使用,现在一切正常。
  • @FominArseniy 它发生了。 :) 谢谢。如果您觉得对您有帮助,请随时接受我的回答。
猜你喜欢
  • 1970-01-01
  • 2018-03-08
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 2012-02-02
  • 2021-09-14
  • 2018-11-15
  • 1970-01-01
相关资源
最近更新 更多