我有一个全局函数,它具有以下签名:
void Systemfehlerprotokollieren(BYTE quelle,WORD fehlercode,WORD subfehlercode,
BYTE klassifizierung, BYTE status,BYTE kanalnummer,DWORD detailfehler,
WORD modulnummer,WORD location,WORD wLenZusatzText,char *pcZusatztext);
我想用两种方法来简化这个函数。
- 使用printf中的变量参数,而不是
pcZusatztext
- 从而去掉参数
wLenZusatzText
- 在本地上下文中使用原始签名
所以我的外部函数(最后的参数)看起来像:
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_start
和va_end
成为条件。