Search code examples
pythonstringpointersctypes

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:\Python32\lib\ctypes\__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;
}

Solution

  • With regards to getting it working, if you pass it a bytes object, it works:

    >>> import ctypes
    >>> ctypes.create_string_buffer(b'hello')
    <ctypes.c_char_Array_6 object at 0x25258c0>
    

    Looking at the code for 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)
    

    Doing it directly,

    >>> (ctypes.c_char * 10)().value = b'123456789'
    

    This works fine.

    >>> (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
    

    This shows that same behaviour. Looks to me as though you've found a bug.

    Time to visit http://bugs.python.org. There are a few bugs related to c_char and create_string_buffer which are in the same field, but none reporting that giving it a str now fails (but there are definite examples showing it used to work in Py3K).