【问题标题】:Is there a way to use _T/TEXT "conditionally" inside a macro?有没有办法在宏中“有条件地”使用 _T/TEXT?
【发布时间】:2012-12-06 08:49:10
【问题描述】:

这个问题是针对 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,a (const) char * 然后将其转换为wchar_t * 如果编译时定义了 _UNICODE。这应该可以工作,假设调用者在fmt 之后为变量参数传递了一个_TCHAR* 字符串(在我的上下文中这是一个合理的假设)。否则,我还必须在格式字符串中将 %s 转换为 %hs,以处理 MS 所称的“ANSI”字符串。

【问题讨论】:

  • FWIW,如果 _UNICODE 未定义,您可以通过使用直接 #define 来稍微改善问题,并且仅包含包装函数。

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


【解决方案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;
}

【讨论】:

  • 这是一个聪明的方法。谢谢!
猜你喜欢
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
  • 2020-02-17
  • 2014-05-25
  • 1970-01-01
相关资源
最近更新 更多