有没有办法在宏内部“有条件地”使用_T / TEXT?

时间:2012-12-19 03:12:47

标签: windows visual-c++ unicode wchar-t tchar

此问题特定于Visual C ++(您可以假设Visual C ++ 2005及更高版本)。

我想为unixoid系统(特别是FreeBSD)中的程序创建粘合代码,以便在Win32上运行并在原始.c文件上进行最少的更改。现在,大部分内容都是直截了当的,但现在我遇到了一个问题。我使用tchar.h标头和TCHAR / _TCHAR,需要为errerrx电话创建粘合代码(请参阅err(3))在原始代码中。请耐心等待,即使您不同意仍然使用tchar.h编写代码。

errerrx的调用大致采用两种形式,这就是问题发生的地方:

err(1, "some string with %d format specifiers and %s such", ...)
/* or */
err(1, NULL, ...)

后者会输出errno中存储的错误(使用strerror)。

现在,问题是,有没有办法编写一个可以同时使用NULL和字符串文字的通用宏?我没有(并且不会)关心变量作为第二个参数传递,只有NULL和文字字符串。

当然,我天真的初始方法没有考虑fmt作为NULL传递(使用可变参数宏!):

#define err(eval, fmt, ...) my_err(eval, _T(fmt), __VA_ARGS__)

现在我对如何使用宏实现这一点没有任何想法,因为它需要一种编译时和运行时条件的混合,这是我目前无法想象的。所以我正在寻找权威的答案,这是否可以想象。

我现在正在采用的方法 - 缺乏更好的方法 - 就是编写一个包装函数,就像errerrx一样接受(const){{ 1}}然后将其转换为char *,如果已定义wchar_t *进行编译。这应该有效,假设调用者在_UNICODE之后为变量参数传递_TCHAR*字符串(这在我的上下文中是一个合理的假设)。否则我还必须在格式字符串中将fmt转换为%s,以处理“ANSI”字符串,就像MS调用它们一样。

1 个答案:

答案 0 :(得分:1)

这是一个解决方案:

#define _WIN32_WINNT 0x0502

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

#ifdef _UNICODE

#define LNULL NULL
#define fn(x) myfn(L ## x)

#else

#define fn(x) myfn(x)

#endif

void myfn(TCHAR * str)
{
    if (str == NULL) _tprintf(_T("<NULL>")); else _tprintf(str);
    _tprintf(_T("\n"));
}

int main(int argc, char ** argv)
{
    fn("hello");
    fn(NULL);
    return 0;
}