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

Posted

技术标签:

【中文标题】将字符串宏/常量转换为宽字符/Unicode【英文标题】:Converting string macros/constants to wide characters/Unicode 【发布时间】:2011-10-03 21:58:38 【问题描述】:

我有一个使用 3rd 方库的 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"

我将各种 静态 链接的库版本信息附加到我的 About Box 以便于版本跟踪,并且将这个常量转换为宽字符串似乎很简单。

我的第一次尝试是 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" 并使其与第 3 方库保持同步。

我知道如果我正在为 Unicode 构建,我可以在运行时转换它,但我认为肯定有一种快速的方法来重新定义这个常量。

---更新---

我用我的包含结构做了一些非常愚蠢的事情,从而错过了情节。修复允许双重定义包装器正常运行的问题。我很愚蠢。

【问题讨论】:

你用的是什么编译器? #define VERSIONSTRW _T(VERSIONSTR) 在 VC++ 2008 中为我工作。 VS2003。我知道它很旧,但目前需要。也许它只是我的编译器中的一个错误? 【参考方案1】:

诀窍是使用两个宏。扩展宏时,参数在被替换到替换列表之前进行宏扩展。所以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' : undeclared identifier 查看我的更新。双宏技巧在 VS2003 中运行良好(后来我假设)。我的愚蠢使我看不到显而易见的事情。

以上是关于将字符串宏/常量转换为宽字符/Unicode的主要内容,如果未能解决你的问题,请参考以下文章

宽字节与多字节互相转换

如何在 IDL 中声明宽字符常量

调用 mbtowc() 时 gcc 如何决定宽字符集?

CDateTimeCtrl控件

根据Unicode码生成汉字

CString 设置宽字符有啥作用