将字符串宏/常量转换为宽字符/Unicode

7

我有一个Unicode Win32应用程序,使用第三方库,其中一些库提供版本信息的常量作为#defined(窄)字符串。例如,libpng提供以下内容:

#define PNG_LIBPNG_VER_STRING "1.5.4"
#define PNG_HEADER_VERSION_STRING \
 " libpng version 1.5.4 - July 7, 2011\n"

我将各种静态链接库的版本信息添加到我的关于框中,以便轻松跟踪版本,并且似乎将此常量转换为宽字符串很简单。我的第一次尝试是TEXT(PNG_HEADER_VERSION_STRING),但是失败了。
#define __TEXT(quote) L##quote

..并且LPNGHEADER_VERSION_STRING当然不存在。

因此,我尝试了几个双重包装宏的组合,以及各种##技巧,试图添加L前缀到一个宏定义的常量中,但未成功。我是否遗漏了一些简单的东西?你会如何处理:

#define VERSIONSTR "Test V1.2.3"
const char* ver= VERSIONSTR;
const wchar* wver = _T(VERSIONSTR); // fails, should be L"Test V1.2.3"
#define VERSIONSTRW _T(VERSIONSTR);  // fails also

以编程方式重新定义常量,而不是简单地添加一个重复的 L"Test V1.2.3" 并且需要与第三方库保持同步。
如果我正在构建 Unicode,我知道可以在运行时进行转换,但我认为肯定有一种快速重新定义此常量的方法。
---更新---
我通过我的包含结构做了一些非常愚蠢的事情,错过了这个问题的关键。修复后,双重定义包装器将按预期工作。这是我的错误。

你正在使用哪个编译器?#define VERSIONSTRW _T(VERSIONSTR) 在 VC++ 2008 中对我有效。 - Tim
VS2003。我知道它很老,但目前需要使用它。也许这只是我的编译器中的一个错误? - CoreyStup
1个回答

7
关键在于使用两个宏。当一个宏被扩展时,其参数会在替换列表中进行宏扩展后再进行替换。因此,WIDEN(VERSIONSTR) 变成了 WIDEN2("Test V1.2.3")
#define WIDEN(quote) WIDEN2(quote)
#define WIDEN2(quote) L##quote

#define VERSIONSTR "Test V1.2.3"
#define VERSIONSTRW WIDEN(VERSIONSTR)

我之前试过那个。VS 仍然出现相同的错误,就像它们之前是单独包装的一样。wchar *str = WIDEN(VERSIONSTR) 的结果是错误 C2065:“LVERSIONSTR”:未声明的标识符。 - CoreyStup
看到我的更新。双重宏技巧在VS2003中可以正常工作(我认为以后版本也可以)。我的愚蠢阻碍了我看到显而易见的东西。 - CoreyStup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接