我有一个具有以下签名的全局函数:
void Systemfehlerprotokollieren(BYTE quelle,WORD fehlercode,WORD subfehlercode,
BYTE klassifizierung, BYTE status,BYTE kanalnummer,DWORD detailfehler,
WORD modulnummer,WORD location,WORD wLenZusatzText,char *pcZusatztext);
这个功能我想以两种方式简化。
pcZusatztext
wLenZusatzText
所以我的外部函数(最后的参数)看起来像是:
ext_Systemfehlerprotokollieren(WORD location, char *form, ...);
此函数应该像以前一样使用上面提到的参数调用void Systemfehlerprotokollieren(. . . )
。
现在我有以下代码部分:
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,"");
[按照@JanKrü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)
还必须更改函数SystemfehlerKG
以反映参数form
。
有一件事我还不是很清楚:
如果我在我最顶层的函数中使用...
并想要调用另一个使用...
签名的函数,那么我必须注意什么?
答案 0 :(得分:1)
您的编辑很容易被发现。在printf
和朋友中,格式字符串不是函数签名的可变参数部分。你必须将它作为正常参数单独传递。
另一个重要的一点是:总是必须将va_list
结构传递给vsnprintf_s
(通过您的vSystemfehlerprotokollieren
),即使您已经确定没有额外的论点。因此,请勿使va_start
和va_end
成为条件。