cppyy 字符串/Unicode#
Python 和 C++ 都有核心类型来表示文本,这些类型应该可以自由互换。cppyy
使这在最常见情况下变得容易,同时在必要时允许自定义以涵盖各种不同的用例(如不同的编解码器)。除了这些核心类型外,还有一系列其他字符类型,从 const char*
和 std::wstring
到 bytes
,它们的使用较少,但也得到了完全支持。
cppyy std::string
#
C++ 的核心类型 std::string
被视为 Python 的 str
等价物,即使纯粹从实现角度来看,它更类似于 bytes
:实际上,C++ 程序员会使用 std::string
的地方,Python 开发者会使用 str
(反之亦然),而不是 bytes
。
然而,Python 的 str
是 unicode
,而 std::string
是基于字符的,因此转换需要编码或解码。为了支持不同的编码,cppyy
推迟了在两种类型之间的隐式转换,直到强制进行转换时,此时默认将 std::string
视为基于 ASCII,并将 str
使用 UTF-8 编解码器。为此,绑定的 std::string
已被 python 化,以允许其作为适当的本地上下文中的多种用途的替代品。
特别是,有时(例如对于接受非 const
引用或指向非 const std::string
变量的指针的函数参数),有必要使用实际的 std::string
实例以允许就地修改。然后这些 python 化操作允许在期望 str
的地方使用它们。例如:
import cppyy
cppyy.cppexec("std::string gs;")
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[1], line 1
----> 1 import cppyy
2 cppyy.cppexec("std::string gs;")
ModuleNotFoundError: No module named 'cppyy'
cppyy.gbl.gs = "hello"
cppyy.gbl.gs
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[2], line 1
----> 1 cppyy.gbl.gs = "hello"
2 cppyy.gbl.gs
NameError: name 'cppyy' is not defined
type(cppyy.gbl.gs) # C++ std::string type
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[3], line 1
----> 1 type(cppyy.gbl.gs) # C++ std::string type
NameError: name 'cppyy' is not defined
d = {"hello": 42} # dict filled with str
d[cppyy.gbl.gs] # drop-in use of std::string -> str
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[4], line 2
1 d = {"hello": 42} # dict filled with str
----> 2 d[cppyy.gbl.gs] # drop-in use of std::string -> str
NameError: name 'cppyy' is not defined
为了处理除UTF-8之外的编解码器,std::string
的 python 化增加了 decode
方法,其签名与 bytes
的相应方法相同。如果已知某个特定的 C++ 函数始终返回代表 unicode
的 std::string
,且使用非 UTF-8 的编解码器,则可以将其显式 python 化以使用该编解码器进行转换。
cppyy std::string_view
#
可以从 Python str
构建一个基于字符的 std::string_view
,但需要将 unicode
对象编码,默认情况下选择 UTF-8。如果 str
中的所有字符都来自 ASCII 集,这将得到预期的结果,但在其他情况下建议在 Python 端进行编码并传递结果 bytes
对象。
cppyy std::wstring
\#
C++ 的“宽”字符串,std::wstring
,基于 wchar_t
,这是一个不太便携的字符类型,因为它的大小可以是 2 字节或 4 字节,取决于平台。cppyy
直接支持 std::wstring
,使用 Python 的 C-API 提供的 wchar_t
数组转换。
cppyy const char*
#
C 表示文本的 const char*
存在两个问题:它不表达所有权;长度是隐式的,即直到第一个 '\0'
出现为止。在一定程度上可以改善第一个问题:在某些情况下可以推断出所有者。特别是,如果 C 字符串是从Python str
设置的,后者拥有内存,绑定代理前者又拥有(未转换的) str
实例。然而,如果 const char*
的内存在 C/C++ 中分配,内存管理必然完全是手动的。另一方面,仅在固定数组的情况下才能知道长度。然而即便如此,更常见的情况是使用固定数组作为缓冲区,实际字符串仍然只延伸到 '\0'
字符,因此这样假设。(C++ 的 `std::string没有这些问题,只要有选择就应该始终优先使用。)
cppyy char*
#
C表示的字符数组 char*
具有 const char*
的所有问题,但除此之外还经常用作“8位int的数据数组”。
cppyy 字符类型#
cppyy
直接支持以下字符类型,既可以作为单个变量也可以作为数组形式:char
, signed char
, unsigned char
, wchar_t
, char16_t
和 char32_t
。