我试着写一个宽版本的__FUNCTION__
来支持可移植代码(Windows和Linux)
#include <stdio.h>
#include <wchar.h>
#include <errno.h>
typedef wchar_t WCHAR;
typedef const wchar_t * PCWCH;
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#ifdef _WIN32
#define __WFUNCTION__ WIDEN(__FUNCTION__) L"(): "
#elif __linux__
#define MAX_FUNC_NAME_SIZE 1024
WCHAR func_name[MAX_FUNC_NAME_SIZE];
#define __WFUNCTION__ \
(AsciiStrToUnicodeStr(__FUNCTION__, func_name, MAX_FUNC_NAME_SIZE) == 0) ? func_name : L"(): "
#endif
int AsciiStrToUnicodeStr(const char *src, WCHAR *destination, unsigned int dest_max)
{
size_t retval;
if (!src || !destination || (dest_max == 0)) {
return -EINVAL;
}
retval = mbstowcs(destination, src, dest_max);
return (retval == -1) ? retval : 0;
}
void DbgTrace(PCWCH pwcFormat,...)
{
wprintf(L"%ls\n", pwcFormat);
}
void test()
{
DbgTrace(__WFUNCTION__ L"ERROR: Null string passed\r\n");
}
int main()
{
DbgTrace(__WFUNCTION__ L"ERROR: Null string passed\r\n");
test();
}
输出仅包含函数的名称,但不包含连接的字符串。
上面的代码有什么错误。
添加了预处理器的输出:
void test()
{
DbgTrace((AsciiStrToUnicodeStr(__FUNCTION__, func_name, 1024) == 0) ? func_name : L"(): " L"ERROR: Null string passed\r\n");
}
__FUNCTION__
(在C99中拼写为__func__
)不是字符串文字;它实际上是一个隐式定义的字符数组。因此,您无法使用文字串联创建字符串文字。 (至少,不是标准C. MSVC可能会将__FUNCTION__
视为字符串文字,但它不可移植。)
字符串文字串联在预处理之后立即完成,并且只能应用于字符串文字,而不能应用于变量。 func_name " extra text"
将是一个语法错误。
但正如你所看到的,这不是宏观扩张所产生的。连接的文字是L"(): " and
L“错误:传递的NULL字符串”。
请注意,如果__func__
是一个字符串文字,您可以将其转换为带有字符串连接的宽字符串文字。例如:
L"" __FILE__ ": the file"
是一个有效的宽字符串文字。 (但它不适用于Windows。请参阅https://stackoverflow.com/a/21789691/1566221)。
由于__func__
不是字符串文字,因此无法在预处理器中扩展它。 (也不能将其转换为宽字符串)。你最好的选择是在printf
电话(或wprintf
)中单独使用它:
printf("%s %s, funcname, message);