c-在函数调用中使用可变数量的参数,并将它们委托给另一个函数



我有一个全局函数,它具有以下签名:

void Systemfehlerprotokollieren(BYTE quelle,WORD fehlercode,WORD subfehlercode,
BYTE klassifizierung, BYTE status,BYTE kanalnummer,DWORD detailfehler,
WORD modulnummer,WORD location,WORD wLenZusatzText,char *pcZusatztext);

我想用两种方法来简化这个函数。

  1. 使用printf中的变量参数,而不是pcZusatztext
  2. 从而去掉参数wLenZusatzText
  3. 在本地上下文中使用原始签名

所以我的外部函数(最后的参数)看起来像:

ext_Systemfehlerprotokollieren(WORD location, char *form, ...);

则该函数应该像以前一样用其上面提到的参数来调用CCD_ 4。

现在我有以下代码部分:

void vSystemfehlerprotokollierenText(BYTE quelle,WORD fehlercode,WORD subfehlercode,
BYTE klassifizierung,BYTE status,BYTE kanalnummer,DWORD detailfehler,
WORD modulnummer,WORD location,va_list args)
{
int ret;
char zepuf_printf_mode_lokal[ZELE];
memset(&zepuf_printf_mode_lokal[0],0x00,ZELE);
ret = vsnprintf_s(zepuf_printf_mode_lokal, ZELE-1,_TRUNCATE, "%s",args );
if (ret != -1)
{
if (ret < 0)
{ 
Systemfehlerprotokollieren(quelle,fehlercode,subfehlercode,
klassifizierung,status,kanalnummer,detailfehler,
modulnummer,location,0,NULL);
return;
}
}
Systemfehlerprotokollieren(quelle,fehlercode,subfehlercode,
klassifizierung,status,kanalnummer,detailfehler,
modulnummer,location,strlen(zepuf_printf_mode_lokal),zepuf_printf_mode_lokal);
}

在上述函数中,Systemfehlerprotokollieren将像通常的一样被调用

void SystemFehlerKG(WORD wFehlerCode, WORD wSubFehlerCode,BYTE KanalNummer,
DWORD detailinfo2, DWORD detailinfo3, WORD programmstelle, char *form, ... )
{
va_list args = NULL ;
if (form != NULL)
{
va_start(args, form);
vSystemfehlerprotokollierenText(SYS_FEHL_QUELLE_FLEXOS,wFehlerCode,wSubFehlerCode, 
SYS_FEHL_KLASS_FEHLER, SYS_FEHL_STATUS_FEHLER_KOMMT_GEHT, KanalNummer, 
(WORD)detailinfo2, (WORD)detailinfo3, programmstelle,args);
va_end(args);
}
else 
vSystemfehlerprotokollierenText(SYS_FEHL_QUELLE_FLEXOS,wFehlerCode,wSubFehlerCode, 
SYS_FEHL_KLASS_FEHLER, SYS_FEHL_STATUS_FEHLER_KOMMT_GEHT, KanalNummer, 
(WORD)detailinfo2, (WORD)detailinfo3, programmstelle,"");
}

当我调用第二个函数时,这很好:

SystemFehlerKG(5000+TCPIP_SYS_ERROR_FKT_SEND,0,SYS_FEHL_KANAL_ALLG,
iRet,0,SFPROG_00000,"%s","");

但我不知道该改变什么才能得到与相同的结果

SystemFehlerKG(5000+TCPIP_SYS_ERROR_FKT_SEND,0,SYS_FEHL_KANAL_ALLG,
iRet,0,SFPROG_00000);

其中省略了最后两个参数。。。

[编辑#1]:

我明白了,printf();也不起作用,它必须至少是printf("");

所以最接近的方法是

SystemFehlerKG(5000+TCPIP_SYS_ERROR_FKT_SEND,0,SYS_FEHL_KANAL_ALLG,
iRet,0,SFPROG_00000,"");

[根据@Jan Krüger的建议编辑#2]:

void SystemFehlerKG(WORD wFehlerCode, WORD wSubFehlerCode,
BYTE KanalNummer, DWORD detailinfo2, DWORD detailinfo3, 
WORD programmstelle, char *form, ... )
{
va_list args = NULL ;
va_start(args, form);
vSystemfehlerprotokollierenText(SYS_FEHL_QUELLE_FLEXOS,wFehlerCode,
wSubFehlerCode, SYS_FEHL_KLASS_FEHLER,
SYS_FEHL_STATUS_FEHLER_KOMMT_GEHT, KanalNummer, 
(WORD)detailinfo2, (WORD)detailinfo3, programmstelle,args);
va_end(args);
}

我现在手头没有代码,但我认为,当form不是有效的(格式)字符串(为NULL或")时,这引发了异常。

我明天告诉你。

[编辑#3:]

我在编辑#2时对代码进行了更改。不起作用。但我发现了错误:

void vSystemfehlerprotokollierenText(BYTE quelle,WORD fehlercode,WORD subfehlercode, BYTE klassifizierung,BYTE status,BYTE kanalnummer,DWORD detailfehler, WORD modulnummer,WORD location,va_list args)

需要

void vSystemfehlerprotokollierenText(BYTE quelle,WORD fehlercode,WORD subfehlercode, BYTE klassifizierung,BYTE status,BYTE kanalnummer,DWORD detailfehler, WORD modulnummer,WORD location,char * form, va_list args)

函数CCD_ 11也必须改变以反映参数CCD_。

有一件事我还不太清楚:如果我在最上面的函数中使用...,并且想调用另一个使用...签名的函数,我必须注意什么?

您的编辑非常到位。在printf和friends中,格式字符串不是函数签名的可变部分的一部分。你必须把它作为一个正常的参数单独传递。

另一个重要的部分是:即使确定没有额外的参数,也必须将va_list结构传递给vsnprintf_s(通过vSystemfehlerprotokollieren)。因此,不要使va_startva_end成为条件。

相关内容

  • 没有找到相关文章

最新更新