create_string_buffer抛出错误TypeError:str/bytes而不是str实例

Hel*_*ali 13 python string ctypes pointers

我正在尝试这个简单的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__.py", line 59, in create_string_buffer
buf.value = init
TypeError: str/bytes expected instead of str instance
Run Code Online (Sandbox Code Playgroud)

有谁知道我做错了什么?

在同一个注释中,我试图从我的python代码将指向字符串的指针传递给C函数,以便我可以在那里执行一些字符串操作并返回另一个字符串.有人可以给我一些关于如何做到这一点的示例代码吗?

extern "C" __declspec(dllexport) char * echo(char* c)
{
      // do stuff
    return c;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*nen 11

您使用的是Python 3,Python 3中的字符串(str-type)是Unicode对象. create_string_buffer创建C char数组,因此您需要传递一个bytes对象.如果您有一个str具有适当编码的bytes对象编码来创建对象.请注意,还有一个create_unicode_buffer创建C wchar数组并使用Python 3 str对象.

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>
Run Code Online (Sandbox Code Playgroud)

关于问题的第二部分,是否要编辑现有字符串或返回在堆上分配的全新字符串?如果是前者,create_string_buffer用于将可变字符串传递给函数并在适当位置修改它将起作用.这是一个从Windows MSVCRT库调用_strupr()的简单示例:

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'
Run Code Online (Sandbox Code Playgroud)

注意将restype函数的(结果类型)设置为c_char_p告诉ctypes将返回值转换为bytes对象.另请注意,_strupr将字符串转换为适当的位置,因此必须传递可变字符串缓冲区.只将Python字节字符串传递给C函数const char*,因为直接通过ctypes修改Python字符串是Bad TM.


Chr*_*gan 8

关于让它工作,如果你传递一个bytes对象,它的工作原理:

>>> import ctypes
>>> ctypes.create_string_buffer(b'hello')
<ctypes.c_char_Array_6 object at 0x25258c0>
Run Code Online (Sandbox Code Playgroud)

查看代码create_string_buffer:

def create_string_buffer(init, size=None):
    """create_string_buffer(aBytes) -> character array
    create_string_buffer(anInteger) -> character array
    create_string_buffer(aString, anInteger) -> character array
    """
    if isinstance(init, (str, bytes)):
        if size is None:
            size = len(init)+1
        buftype = c_char * size
        buf = buftype()
        buf.value = init
        return buf
    elif isinstance(init, int):
        buftype = c_char * init
        buf = buftype()
        return buf
    raise TypeError(init)
Run Code Online (Sandbox Code Playgroud)

直接这样做,

>>> (ctypes.c_char * 10)().value = b'123456789'
Run Code Online (Sandbox Code Playgroud)

这很好用.

>>> (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
Run Code Online (Sandbox Code Playgroud)

这表明了同样的行为.看起来好像你发现了一个bug.

是时候访问http://bugs.python.org了.有相关的一些错误,c_char以及create_string_buffer它们是在同一领域,但没有报告说,给它str现在失败(但也有显示它用于Py3K工作的明确的例子).