Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
701 views
in Technique[技术] by (71.8m points)

python - create_string_buffer throwing error TypeError: str/bytes expected instead of str instance

I am trying this simple ctypes example and getting the error mentioned

>>> from ctypes import create_string_buffer
>>> str = create_string_buffer("hello")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:Python32libctypes\__init__.py", line 59, in create_string_buffer
buf.value = init
TypeError: str/bytes expected instead of str instance

Does anyone know what am I doing wrong?

On the same note, I am trying to pass a pointer to a string to a C function from my python code so that I can perform some string operation there and return another string. Can someone give me some sample code on how to do that?

extern "C" __declspec(dllexport) char * echo(char* c)
{
      // do stuff
    return c;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You're using Python 3, and strings (str-type) in Python 3 are Unicode objects. create_string_buffer creates C char arrays, so you are required to pass a bytes object. If you have a str object encode with an appropriate encoding to create a bytes object. Note there is a create_unicode_buffer that creates C wchar arrays as well and takes Python 3 str objects.

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>

In regards to the 2nd part of your question, do you want to edit the existing string or return an entirely new string allocated on the heap? If the former, using create_string_buffer to pass an mutable string to the function and modifying it in place will work. Here's a simple example calling _strupr() from the Windows MSVCRT library:

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'

Note setting the restype (result type) of the function to a c_char_p tells ctypes to convert the return value to a bytes object. Also note that _strupr converts a string in place, so a mutable string buffer must be passed. Only pass Python byte strings to C functions that take const char*, since modifying Python strings directly via ctypes is BadTM.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...