将CFString转换为Python字符串

时间:2012-05-03 09:40:53

标签: python core-foundation

我有一个CFString,想在Python中使用它。

最快的方法是什么?是否有可能避免转换,即以某种方式仅从CFString指针创建Python字符串?

2 个答案:

答案 0 :(得分:1)

  

是否可以避免转换,即以某种方式仅从CFString指针创建Python字符串?

不是我知道的。 Python是跨平台的,即使它们可用,也没有任何理由在内部使用CFStrings。

可以能够获得字符串的支持C stringMacRoman Pascal stringUTF-16 character buffer,但是其中每一个都可以失败,所以你不能依赖他们中的任何一个工作。您必须始终将字符复制到您自己的缓冲区作为最后一次尝试。

你甚至不应该尝试Pascal-string路由,因为你仍然需要从MacRoman转换为UTF-8。您也可以在此时使用字符串自己的转换API。

  

[转换]的最快方法是什么?

如果上述任何一个快捷方式(除了Pascal-string之一)成功,它将是最快的方式。

无论如何,您需要获取包含某种形式的字符的缓冲区,然后从该缓冲区创建一个Python字符串。

此时值得一提的是,在Python 2.x中,str类型是纯粹的8位数据对象。出于这个原因,Python 3将其重命名为bytes,您应该将其视为与NS / CFData相对应的Python,而不是NS / CFString。

NS / CFStrings包含Unicode字符,因此您需要Python's unicode (str in Python 3) type

小心CFStringGetLength:它以UTF-16代码单位返回长度。如果您最终使用UTF-8,则UTF-8代码单元的长度可能会有所不同。

从Python文档中,您可以根据自己从CFString中获得的内容创建Python字符串:

TL; DR

仅使用Python的unicode(PyUnicode)类;不是str / bytes / PyString / PyBytes

我先尝试GetCStringPtr(请求UTF-8)。如果成功,我会调用CFStringGetMaximumSizeForEncoding来确定(希望比strlen更长的字符串长度,然后调用PyUnicode_FromStringAndSize来创建Python字符串。

接下来,我会问CFString what's the fastest encoding to convert it to

  • 如果最快的编码是UTF-16(或者,正如CFString所称的那样,“Unicode”),我会使用CFStringGetLengthCFStringGetCharactersPtrCFStringGetCharacters(如果{{1} }}}}和GetCharactersPtr
  • 否则,我会使用the CFStringGetBytes function一次来确定转换为UTF-8所需的缓冲区大小,然后再次执行该转换,然后PyUnicode_FromUnicode

(我应该指出,“if”可能是过早优化。PyUnicode_FromStringAndSize是CFString的中心文本编码转换函数;它能够返回任何编码,包括UTF -16。您可能希望同时编写条件CFStringGetBytes解决方案和无条件CFStringGetCharacters{Ptr,}解决方案,并将它们相互对齐,以及查看字符串中实际上最快的编码是否为UTF-16你正在处理。)

答案 1 :(得分:-2)

为什么你想在python中使用CFString .. BTW CF字符串有自己的结构定义,它存储在内存中的方式与python字符串不同。它无法进行此转换。