ctypes c_char_p的不同行为? [英] Different behaviour of ctypes c_char_p?

查看:82
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆