我对不同版本的python的这种行为感到困惑,不明白为什么?
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
一个有效,而另一个给我一个错误。哪一个是正确的?
如果两者都正确,我怎样才能达到与3.3.5中2.7相同的行为?我想将char指针从python传递给C.
答案 0 :(得分:17)
c_char_p
是_SimpleCData
的子类,_type_ == 'z'
。 __init__
方法调用类型setfunc
,对于简单类型'z'
,z_set
为str
。
在Python 2中,编写z_set
function(2.7.7)来处理unicode
和str
字符串。在Python 3之前,str
是一个8位字符串。 CPython 2.x \0
在内部使用一个以C结尾的字符串(即由z_set
终止的字节数组),str
可以调用PyString_AS_STRING
(即得到一个指向unicode
对象的内部缓冲区的指针。首先需要将z_set
字符串编码为字节字符串。 _objects
自动处理此编码,并在>>> c = u'spam'
>>> a = c_char_p(c)
>>> a._objects
'spam'
>>> type(a._objects)
<type 'str'>
属性中保留对已编码字符串的引用。
'mbcs'
在Windows上,默认的ctypes字符串编码为'ignore'
,错误处理设置为'ascii'
。在所有其他平台上,默认编码为'strict'
,错误处理为set_conversion_mode('utf-8', 'strict')
。要修改默认值,请致电ctypes.set_conversion_mode
。例如,str
。
在Python 3中,z_set
function(3.4.1)不会自动将bytes
(现在为Unicode)转换为set_conversion_mode
。范例在Python 3中转移到严格划分二进制数据中的字符串。删除了ctypes默认转换,函数c_char_p
也是如此。您必须传递bytes
b'spam'
个对象(例如'spam'.encode('utf-8')
或z_set
)。在CPython 3.x中,bytes
调用C-API函数PyBytes_AsString
来获取指向c_char
对象的内部缓冲区的指针。
请注意,如果C函数修改了字符串,则需要使用create_string_buffer
来创建const
数组。查找要输入c_char_p
的参数,以便知道使用{{1}}是安全的。