我试图编写__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");
}
答案 0 :(得分:0)
__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);