如何避免在 C/C++ API 中编码字符串混淆?
Posted
技术标签:
【中文标题】如何避免在 C/C++ API 中编码字符串混淆?【英文标题】:How can I avoid encoding mixups of strings in a C/C++ API? 【发布时间】:2010-05-21 10:23:05 【问题描述】:我正致力于在 C 和 C++ 中实现不同的 API,并且想知道有哪些技术可用于避免客户端在从框架接收字符串或将字符串传回时出现编码错误。例如,想象一个简单的 C++ 插件 API,客户可以实施它来影响翻译。它可能具有这样的功能:
const char *getTranslatedWord( const char *englishWord );
现在,假设我要强制所有字符串都以 UTF-8 格式传递。当然我会记录这个要求,但我希望编译器强制执行正确的编码,也许通过使用专用类型。例如,这样的事情:
class Word
public:
static Word fromUtf8( const char *data ) return Word( data );
const char *toUtf8() return m_data;
private:
Word( const char *data ) : m_data( data )
const char *m_data;
;
我现在可以在 API 中使用这种特殊类型:
Word getTranslatedWord( const Word &englishWord );
不幸的是,这很容易导致效率低下。 Word
类缺少适当的复制构造函数、赋值运算符等。我想尽可能避免不必要的数据复制。另外,我看到Word
被越来越多的实用功能(如length
或fromLatin1
或substr
等)扩展的危险,我宁愿不编写又一个字符串类。我只想要一个避免意外编码混淆的小容器。
我想知道是否其他人对此有一些经验并可以分享一些有用的技术。
编辑:在我的特殊情况下,该 API 在 Windows 和 Linux 上使用 MSVC 6 - Windows 上的 MSVC 10 和 Linux 上的 gcc 3 和 4。
【问题讨论】:
@Anders:我更新了我的问题来回答你的评论。 【参考方案1】:你可以传递一个 std::pair 而不是一个 char*:
struct utf8_tag_t utf8_tag;
std::pair<const char*,utf8_tag_t> getTranslatedWord(std::pair<const char*,utf8_tag_t> englishWord);
在一个体面的现代编译器上生成的机器代码应该是相同的,该编译器对 std::pair 使用空基类优化。
不过我不介意。我只是使用 char*s 并记录输入必须是 utf8。如果数据可能来自不受信任的来源,那么无论如何您都必须在运行时检查编码。
【讨论】:
【参考方案2】:我建议你使用std::wstring
。
查看this其他问题了解详情。
【讨论】:
是的,std::wstring 看起来像一个候选人。但是,我想知道是否有一些东西不需要人们将他们的插件与标准 C++ 库链接起来。至少在 Visual Studio 2009 中,据我所知,它并不是所有的内联模板魔法。 使用 std::wstring 不是一个好主意。它是 wchar_t 的序列——在 Microsoft 编译器上是 16 位整数类型,在 gcc 上是 32 位整数类型。所以一个 std::wstring 可以合理地包含 utf16LE、utf16BE、utf32BE 或 utf32LE。【参考方案3】:ICU 项目为 C++ 提供 Unicode 支持库。
【讨论】:
没错,但我不想引入一个全新的库。 除非你需要它提供的其他功能……以上是关于如何避免在 C/C++ API 中编码字符串混淆?的主要内容,如果未能解决你的问题,请参考以下文章
Github GraphQL API,硬编码访问令牌有效,试图混淆它没有