在跨平台C和C++ API中使用字符串的当前最佳实践是什么?

Phi*_* P. 10 c c++ api cross-platform

我看起来可能需要开始一些跨平台项目,其中一部分必须用C或C++完成(尚未确定,因此问题是关于它们两者).我将主要处理基于文本的东西和字符串.

C/C++将具有可从更高级别的平台相关代码调用的API.

我的问题是:建议使用什么类型的字符串,特别是在声明公共接口时?有没有推荐的标准技术?有什么可以避免的吗?

我几乎没有编写C或C++代码的经验,甚至那都是在Windows上,所以没有什么比这更像是跨平台了.所以我真正想要的是让某些东西能够让我以正确的方式行事,避免做出愚蠢的事情,这些事情必将引起很多痛苦.


编辑1:提供有关预期用途的更多上下文.API将被以下消费者使用:

  • 通过NSString和朋友在iPhone/iPad/Mac上实现目标C. API可以静态链接,因此无需担心.so .dll问题.

  • Java通过JNI在Android和其他Java平台上运行

  • .NET通过p/invoke从托管C#代码或本机静态链接(如果使用C++/CLI).

  • 关于在这种情况下以某种方式/某处使用lua有一些想法.不知道这是否与任何事情有关.

Meh*_*dad 15

规则

  • 使用UTF格式来存储字符串,而不是 "代码页"或诸如此类的东西(UTF-16可能更容易编辑:我完全忘记了字节顺序问题; UTF-8可能是要走的路).

  • 使用以null结尾的字符串而不是计数字符串,因为这些字符串最容易从大多数语言访问.但要注意缓冲区溢出.
    6年后更新:我推荐这个API是出于互操作性的原因(因为很多人已经使用了null终止,并且有多种方法来表示计数字符串),而不是最佳设计观点中的最佳方法.今天我可能会说前者不那么重要,如果可以的话,建议使用count字符串而不是以null结尾的字符串.

  • 甚至不要尝试使用类std::string来向用户传递字符串.升级编译器/库后,甚至你自己的程序也会破坏(因为它们的实现细节就是:实现细节),更不用说非C++程序会遇到问题.
    6年后更新:这完全是出于其他语言的语言和ABI兼容性原因,而不是C++程序开发的一般建议.如果您正在进行C++开发,跨平台或其他方式,请使用STL!即如果您需要从其他语言调用您的代码,请仅遵循此建议.

  • 避免为用户分配字符串,除非对用户来说真的很痛苦.相反,请使用缓冲区并填充数据.这样您就不必强制用户使用特定功能来释放数据.(这通常也是一个性能优势,因为它允许用户在堆栈上分配小缓冲区.但是如果你这样做,提供你自己的函数来释放数据.你不能假设你malloc或者new可以被释放与他们freedelete- 他们经常不能.)

注意:

只是为了澄清,"让用户分配缓冲区"和"使用以NULL结尾的字符串" 不会相互竞争.您仍然需要从用户获取缓冲区长度,但在终止字符串时包含NULL.我的观点并不是你应该创建一个类似的函数scanf("%s"),这显然是非常危险的 - 你仍然需要用户的缓冲区长度.即做几乎Windows在这方面的工作.

  • 根据他的所作所为,UTF-8可能是最简单的. (7认同)
  • 在某些平台上,wchar_t是16位(Windows),其他地方是32位(Linux,Mac OS X),所以要小心内存布局.对于文件名,Windows使用UTF-16,Linux和Mac使用UTF-8,但很容易在两者之间进行转换.UTF-8很简单,因为通常没有字节顺序问题.在UTF-16中,您可能必须描述字节顺序.理论上wchar_t可以是UTF-16或UTF-32,MSB或LSB.这就是UTF-8在协议中更容易的原因. (4认同)
  • @James:我实际上会提到这一点,但我担心有人读这篇文章可能会错误地开始使用带有Windows API函数的`___ A`版本的UTF-8(而不是正确地将它们转换为UTF-16,有点烦人),所以我说的是UTF-16.但是,如果你不太关心这个潜在的事故,那么UTF-8确实可能是最容易的. (3认同)