Python 创建\u字符串\u缓冲区引发错误类型错误:应为str/字节,而不是str实例
我正在尝试这个简单的ctypes示例,并得到了提到的错误Python 创建\u字符串\u缓冲区引发错误类型错误:应为str/字节,而不是str实例,python,string,pointers,ctypes,Python,String,Pointers,Ctypes,我正在尝试这个简单的ctypes示例,并得到了提到的错误 >>> from ctypes import create_string_buffer >>> str = create_string_buffer("hello") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python32\lib\ctypes\__init_
>>> from ctypes import create_string_buffer
>>> str = create_string_buffer("hello")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python32\lib\ctypes\__init__.py", line 59, in create_string_buffer
buf.value = init
TypeError: str/bytes expected instead of str instance
该参数是字符串所需的缓冲区大小,因此请将缓冲区的长度传递给它。它将创建该大小的字符数组
>>> from ctypes import create_string_buffer
>>> buf = create_string_buffer(20)
>>> buf
<ctypes.c_char_Array_20 object at 0x355348>
>>>
>>从ctypes导入创建字符串缓冲区
>>>buf=创建字符串缓冲区(20)
>>>buf
>>>
关于如何让它工作,如果您向它传递一个字节
对象,它将工作:
>>> import ctypes
>>> ctypes.create_string_buffer(b'hello')
<ctypes.c_char_Array_6 object at 0x25258c0>
直接做,
>>> (ctypes.c_char * 10)().value = b'123456789'
这个很好用
>>> (ctypes.c_char * 10)().value = '123456789'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: str/bytes expected instead of str instance
>(ctypes.c_char*10)()。值='123456789'
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:应为str/字节,而不是str实例
这表明了同样的行为。在我看来,你好像发现了一只虫子
参观的时间到了。与
c\u char
和create\u string\u buffer
相关的一些bug位于同一个字段中,但是没有一个报告说给它一个str
现在失败了(但是有明确的例子显示它在Py3K中工作)。您使用的是Python 3,而Python 3中的字符串(str
-type)是Unicode对象create_string\u buffer
创建Cchar
数组,因此需要传递一个bytes
对象。如果您有一个str
对象,请使用适当的编码进行编码,以创建一个bytes
对象。注意,还有一个create\u unicode\u buffer
可以创建Cwchar
数组,并接受python3str
对象
Python 3.2.1 (default, Jul 10 2011, 21:51:15) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.create_unicode_buffer('abcd')
<ctypes.c_wchar_Array_5 object at 0x00C2D300>
>>> ctypes.create_string_buffer(b'abcd')
<ctypes.c_char_Array_5 object at 0x00C2D1C0>
>>> ctypes.create_string_buffer('abcd'.encode('utf-8'))
<ctypes.c_char_Array_5 object at 0x00C2D300>
注意:将函数的
restype
(结果类型)设置为c\u char\p
会告诉ctypes将返回值转换为字节
对象。还请注意,\u strupr
就地转换字符串,因此必须传递可变字符串缓冲区。只将Python字节字符串传递给采用const char*
的C函数,因为直接通过ctypes修改Python字符串是BadTM。请永远不要分配给str
(这不是这里的问题)。暗影是邪恶的,我明白了。但是如何将缓冲区初始化为字符串值呢?最后,我如何将其传递给C方法?谢谢。感谢您提供了以字节对象传递的解决方案。你能回答问题的后面部分吗?在python中,如何打印作为指针从C方法返回的字符串值?@Helali:我不知道。我从未用Python处理过C代码。如果你有一个ctypes.c\u char\u Array.*
实例,它只是thingy.value
,但我想这不是你的问题。@eryksun:我不在乎这个c_char
数组用于接受str
,并且仍然声称接受,但不再接受。因此,这是一种倒退。他们是否选择改变记录的行为而不是修复回归是他们的选择。但是这是一个bug。ctypes.create\uUnicode\uBuffer('abcd')
对你有用吗?在Ubuntu 11.04 64位上的Python3.2(不是我看到的3.2.1)上它对我不起作用,而且它显然对@Helali不起作用。是的,它对我起作用。我查看了3.2.1的发行说明,没有发现需要bytes
来解决create\u string\u buffer
的问题,但是我确实发现这个问题()说str
到bytes
的隐式转换是不允许的。
>>> (ctypes.c_char * 10)().value = '123456789'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: str/bytes expected instead of str instance
Python 3.2.1 (default, Jul 10 2011, 21:51:15) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.create_unicode_buffer('abcd')
<ctypes.c_wchar_Array_5 object at 0x00C2D300>
>>> ctypes.create_string_buffer(b'abcd')
<ctypes.c_char_Array_5 object at 0x00C2D1C0>
>>> ctypes.create_string_buffer('abcd'.encode('utf-8'))
<ctypes.c_char_Array_5 object at 0x00C2D300>
Python 3.2.1 (default, Jul 10 2011, 21:51:15) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> c = ctypes.CDLL('msvcr90.dll')
>>> strupr = c._strupr
>>> a=ctypes.create_string_buffer(b'abc')
>>> strupr.restype=ctypes.c_char_p
>>> strupr(a)
b'ABC'