如何在一系列包装器函数调用中正确使用va_list



我有一个用于微控制器的以太网库(keil rl-tcpnet for lpc2478)。库在调试输出函数中使用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配置文件,我编写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 ?

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

您需要显式地接受printDebugMsg()va_list参数,因为这是您传递的。例如,vprintf()解决了printf()系列的这个问题。

最新更新