ctypes c_char_p的不同行为? [英] Different behaviour of ctypes c_char_p?
问题描述
我对不同版本的python的这种行为感到困惑,并且不明白为什么?
I am confused with this behaviour of different versions of python and dont understand why ?
Python 2.7.5 (default, Aug 25 2013, 00:04:04)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> c="hello"
>>> a=ctypes.c_char_p(c)
>>> print(a.value)
hello
Python 3.3.5 (default, Mar 11 2014, 15:08:59)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> c="hello"
>>> a=ctypes.c_char_p(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bytes or integer address expected instead of str instance
一个工作,而另一个给我一个错误.哪一个是正确的?
One works while the other gives me an error. Which one is correct ?
如果两个都是正确的,我如何获得与3.3.5中的2.7相同的行为?我想将char指针从python传递给C.
If both of them are correct, how can i achieve the same behaviour as 2.7 in 3.3.5 ? I want to pass the char pointer to C from python.
推荐答案
c_char_p
是 _SimpleCData
的子类,其中 _type_ =='z'代码>.
__ init __
方法调用该类型的 setfunc
,对于简单类型'z'
,该类型为 z_set
.
c_char_p
is a subclass of _SimpleCData
, with _type_ == 'z'
. The __init__
method calls the type's setfunc
, which for simple type 'z'
is z_set
.
在Python 2中, z_set
函数(2.7.7)用于处理 str
和 unicode
字符串.在Python 3之前, str
是8位字符串.CPython 2.x str
内部使用一个以C终止的字符串(即以 \ 0
终止的字节数组), z_set
可以为此调用 PyString_AS_STRING
(即获取指向内部缓冲区的指针 str
对象).首先需要将 unicode
字符串编码为字节字符串. z_set
自动处理此编码,并在 _objects
属性中保留对已编码字符串的引用.
In Python 2, the z_set
function (2.7.7) is written to handle both str
and unicode
strings. Prior to Python 3, str
is an 8-bit string. CPython 2.x str
internally uses a C null-terminated string (i.e. an array of bytes terminated by \0
), for which z_set
can call PyString_AS_STRING
(i.e. get a pointer to the internal buffer of the str
object). A unicode
string needs to first be encoded to a byte string. z_set
handles this encoding automatically and keeps a reference to the encoded string in the _objects
attribute.
>>> c = u'spam'
>>> a = c_char_p(c)
>>> a._objects
'spam'
>>> type(a._objects)
<type 'str'>
在Windows上,默认的ctypes字符串编码为'mbcs'
,错误处理设置为'ignore'
.在所有其他平台上,默认编码为'ascii'
,并带有'strict'
错误处理.要修改默认值,请调用 ctypes.set_conversion_mode
.例如, set_conversion_mode('utf-8','strict')
.
On Windows, the default ctypes string encoding is 'mbcs'
, with error handling set to 'ignore'
. On all other platforms the default encoding is 'ascii'
, with 'strict'
error handling. To modify the default, call ctypes.set_conversion_mode
. For example, set_conversion_mode('utf-8', 'strict')
.
在Python 3中, z_set
函数(3.4.1)不会自动将 str
(现在为Unicode)转换为 bytes
.Python 3中的范例进行了转变,以严格将字符串与二进制数据分开.ctypes的默认转换以及函数 set_conversion_mode
均被删除.您必须传递 c_char_p
一个 bytes
对象(例如 b'spam'
或'spam'.encode('utf-8')
).在CPython 3.x中, z_set
调用C-API函数 PyBytes_AsString
获取指向 bytes
对象的内部缓冲区的指针.
In Python 3, the z_set
function (3.4.1) does not automatically convert str
(now Unicode) to bytes
. The paradigm shifted in Python 3 to strictly divide character strings from binary data. The ctypes default conversions were removed, as was the function set_conversion_mode
. You have to pass c_char_p
a bytes
object (e.g. b'spam'
or 'spam'.encode('utf-8')
). In CPython 3.x, z_set
calls the C-API function PyBytes_AsString
to get a pointer to the internal buffer of the bytes
object.
请注意,如果C函数修改了字符串,则需要改为使用 create_string_buffer
创建一个 c_char
数组.查找要键入为 const
的参数,以了解使用 c_char_p
是安全的.
Note that if the C function modifies the string, then you need to instead use create_string_buffer
to create a c_char
array. Look for a parameter to be typed as const
to know that it's safe to use c_char_p
.
这篇关于ctypes c_char_p的不同行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!