在Linux中扩展__FUNCTION__的版本

问题描述 投票:1回答:1

我试着写一个宽版本的__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");
}
c linux windows printf c-preprocessor
1个回答
0
投票

__FUNCTION__(在C99中拼写为__func__)不是字符串文字;它实际上是一个隐式定义的字符数组。因此,您无法使用文字串联创建字符串文字。 (至少,不是标准C. MSVC可能会将__FUNCTION__视为字符串文字,但它不可移植。)

字符串文字串联在预处理之后立即完成,并且只能应用于字符串文字,而不能应用于变量。 func_name " extra text"将是一个语法错误。

但正如你所看到的,这不是宏观扩张所产生的。连接的文字是L"(): " andL“错误:传递的NULL字符串”。

请注意,如果__func__是一个字符串文字,您可以将其转换为带有字符串连接的宽字符串文字。例如:

L"" __FILE__ ": the file"

是一个有效的宽字符串文字。 (但它不适用于Windows。请参阅https://stackoverflow.com/a/21789691/1566221)。

由于__func__不是字符串文字,因此无法在预处理器中扩展它。 (也不能将其转换为宽字符串)。你最好的选择是在printf电话(或wprintf)中单独使用它:

 printf("%s %s, funcname, message);
© www.soinside.com 2019 - 2024. All rights reserved.