首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Xerces-c和跨平台字符串文本

Xerces-c和跨平台字符串文本
EN

Stack Overflow用户
提问于 2014-09-11 08:03:49
回答 1查看 1K关注 0票数 2

我正在将使用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.

我从这条赛道出发:

代码语言:javascript
复制
#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代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-16 01:39:53

答案是,没有人对如何做这件事有一个好主意。对于其他发现这个问题的人来说,这就是我想出的:

代码语言:javascript
复制
#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函数签名)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25782247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档