gpt4 book ai didi

c++ - Xerces-c 和跨平台字符串文字

转载 作者:太空宇宙 更新时间:2023-11-04 11:28:22 29 4
gpt4 key购买 nike

我正在将使用 Xerces-c 进行 XML 处理的代码库从 Windows/VC++ 移植到 Linux/G++。

在 Windows 上,Xerces-c 使用 wchar_t 作为字符类型 XmlCh。这允许人们使用 std::wstringL"" 语法的字符串文字。

在 Linux/G++ 上,wchar_t 是 32 位的,Xerces-c 使用 unsigned short int(16 位)作为字符类型 XmlCh.

我已经沿着这条轨道开始了:

#ifdef _MSC_VER
using u16char_t = wchar_t;
using u16string_t = std::wstring;
#elif defined __linux
using u16char_t = char16_t;
using u16string_t = std::u16string;
#endif

不幸的是,char16_tunsigned short int 并不等价,它们的指针不可隐式转换。因此,将 u"Hello, world." 传递给 Xerces 函数仍然会导致无效转换错误。

开始看起来我必须显式转换传递给 Xerces 函数的每个字符串。但在我这样做之前,我想问问是否有人知道编写跨平台 Xerces-c 代码的更明智的方法。

最佳答案

答案是否定的,没有人知道如何做到这一点。对于发现这个问题的任何其他人,这就是我想出的:

#ifdef _MSC_VER
#define U16S(x) L##x
#define U16XS(x) L##x

#define XS(x) x
#define US(x) x

#elif defined __linux

#define U16S(x) u##x
#define U16XS(x) reinterpret_cast<const unsigned short *>(u##x)

inline unsigned short *XS(char16_t* x) {
return reinterpret_cast<unsigned short *>(x);
}
inline const unsigned short *XS(const char16_t* x) {
return reinterpret_cast<const unsigned short *>(x);
}
inline char16_t* US(unsigned short *x) {
return reinterpret_cast<char16_t *>(x);
}
inline const char16_t* US(const unsigned short *x) {
return reinterpret_cast<const char16_t*>(x);
}

#include "char16_t_facets.hpp"
#endif

namespace SafeStrings {
#if defined _MSC_VER

using u16char_t = wchar_t;
using u16string_t = std::wstring;
using u16sstream_t = std::wstringstream;
using u16ostream_t = std::wostream;
using u16istream_t = std::wistream;
using u16ofstream_t = std::wofstream;
using u16ifstream_t = std::wifstream;
using filename_t = std::wstring;

#elif defined __linux

using u16char_t = char16_t;
using u16string_t = std::basic_string<char16_t>;
using u16sstream_t = std::basic_stringstream<char16_t>;
using u16ostream_t = std::basic_ostream<char16_t>;
using u16istream_t = std::basic_istream<char16_t>;
using u16ofstream_t = std::basic_ofstream<char16_t>;
using u16ifstream_t = std::basic_ifstream<char16_t>;
using filename_t = std::string;

#endif

char16_t_facets.hpp具有模板特化的定义 std::ctype<char16_t> , std::numpunct<char16_t> , std::codecvt<char16_t, char, std::mbstate_t> .有必要将这些与 std::num_get<char16_t> 一起添加到全局语言环境中和 std::num_put<char16_t> (但没有必要为这些提供特化)。 codecvt 的代码是唯一困难的一点,可以在 GCC 5.0 库中找到一个合理的模板(如果您使用 GCC 5,则不需要提供 codecvt 特化,因为它已经在库中)。

完成所有这些后,char16_t流将正常工作。

然后,每次定义一个宽字符串,而不是L"string" , 写 U16S("string") .每次将字符串传递给 Xerces 时,为文字编写 XS(string.c_str()) 或 U16XS("string")。每次从 Xerces 获取字符串时,将其转换回 u16string_t(US(call_xerces_function())) .

请注意,也可以将字符类型设置为 char16_t 来重新编译 Xerces-C。这消除了上面所需的大量工作。 但是您将无法在系统上使用任何其他依赖于 Xerces-C 的库。链接到任何此类库都会导致链接错误(因为更改字符类型会更改许多 Xerces 函数签名)。

关于c++ - Xerces-c 和跨平台字符串文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25782247/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com