【发布时间】:2021-11-18 03:07:03
【问题描述】:
我的尝试看起来很老套,而且过于复杂。有没有在 Windows 和 macOS 上将 ASCII 转换为 UTF16 的简单方法?
(注意prUTF16Char我不能改????)
尝试(写自https://stackoverflow.com/a/54376330)
前奏
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if defined(__APPLE__) && defined(__MACH__)
#include <xcselect.h>
#include <wchar.h>
#include <CoreFoundation/CoreFoundation.h>
typedef unsigned short int prUTF16Char;
#else
typedef wchar_t prUTF16Char;
#endif
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define PROJECT_NAME "foo"
功能
void copy2ConvertStringLiteralIntoUTF16(const wchar_t* inputString, prUTF16Char* destination) {
size_t length = wcslen(inputString);
#if (defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)) && defined(PLUGIN_MODE)
wcscpy_s(destination, length + 1, inputString);
#elif defined(__APPLE__) && defined(__MACH__)
CFRange range = {0, 150}; range.length = length;
CFStringRef inputStringCFSR = CFStringCreateWithBytes(
kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(inputString),
length * sizeof(wchar_t), kCFStringEncodingUTF32LE, false);
CFStringGetBytes( inputStringCFSR, range, kCFStringEncodingUTF16, 0, false,
reiterpret_cast<UInt8 *>(destination), length * (sizeof (prUTF16Char)), NULL);
destination[length] = 0; // Set NULL-terminator
CFRelease(inputStringCFSR);
#endif
}
const prUTF16Char * to_wchar(const char* message) {
const size_t cSize = strlen(message);
wchar_t *w_str = new wchar_t[cSize];
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
size_t outSize;
mbstowcs_s(&outSize, w_str, cSize, message, cSize-1);
return w_str;
#else
mbstowcs(w_str, message, cSize);
#endif
#if defined(__APPLE__) && defined(__MACH__)
prUTF16Char *ut16str = new prUTF16Char[cSize];
copy2ConvertStringLiteralIntoUTF16(w_str, ut16str);
return ut16str;
#else
return w_str;
#endif
}
然后我可以定义一个全局变量:
static const prUTF16Char* PROJECT_NAME_W =
#if defined(__APPLE__) && defined(__MACH__)
to_wchar
#elif defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
WIDEN
#endif
(PROJECT_NAME);
以及采用message 的通用打印函数的主体:
#if WCHAR_UTF16
wprintf(L"%s",
#else
printf("%ls\n",
#endif
message);
全面尝试:
https://github.com/SamuelMarks/premiere-pro-cmake-plugin/blob/f0d2278/src/common/logger.cpp [从 C++ 重写为 C]
错误:
错误:初始化元素不是编译时常量
编辑:超级hacky,但使用@barmak-shemirani 的解决方案我可以:
#if defined(__APPLE__) && defined(__MACH__)
extern
#elif defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
static
#endif
const prUTF16Char* PROJECT_NAME_W
#if defined(__APPLE__) && defined(__MACH__)
;
#elif defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
WIDEN(PROJECT_NAME);
#endif
...并且仅在 extern 变体上初始化和 free。
【问题讨论】:
-
这被标记为 C 但包含
new,你是不是忘了替换它? -
"Convert ASCII to [Unicode]" 被混淆了; ASCII 已经是 Unicode 的一个子集。您能否请edit 更详细地解释代码应该做什么?简单来说,纯 ASCII 字符串
"hello"对应于 UTF-16 中的"h\x00e\x00l\x00l\x00o\x00"(尽管在常规 C 字符串中空字节显然会出现问题......首选 utf8everywhere.org 的众多原因之一) -
@BarmakShemirani - 是的,当我意识到这一切似乎太复杂时,我仍在从 C++ 转换的演员表。 @tripleee 另外我在 C90 中工作,所以我实际上不能在任何地方使用 UTF8……更不用说我符合其他人的 API [Adobe's] 并且需要在某些地方接受常规的
const char*输入(我需要转换为 API 使用的 unicode 变体)
标签: c character-encoding wchar-t wchar multibyte-characters