Sending stucture containing mutable string to C from Python thru ctypes

Go To StackoverFlow.com

2

I have a structure which contains character array on C side

stuct s
{
    int x;
    char buffer[100];
}

and on my python side I define

class myS(ctypes.Structure):
    _fields_ = [("x", c_int),
         ("buffer",type(create_string_buffer(100)))]

Now, when I do

buf = create_string_buffer(64)
s1 = myS(10,buf)

It gives me error

TypeError: expected string or Unicode object, c_char_Array_100 found

I want a string which will be changed by my C function. how to do it?

2012-04-04 07:21
by Sudip
i have also tried cchar*100 in place of type(createstring_buffer(100)) resulting in same output - Sudip 2012-04-04 07:43


1

You don't have to create a buffer. The buffer is in the structure when you instantiate it.

Here's a quick DLL:

#include <string.h>

struct s
{
    int x;
    char buffer[100];
};

__declspec(dllexport) void func(struct s* a)
{
    a->x = 5;
    strcpy(a->buffer,"here is the contents of the string.");
}

And here's Python code to call it:

import ctypes

class myS(ctypes.Structure):
    _fields_ = [
        ("x", ctypes.c_int),
        ("buffer",ctypes.c_char * 100)]

s1 = myS()
dll = ctypes.CDLL('test')
dll.func(ctypes.byref(s1))
print s1.buffer
print s1.x

Output:

here is the contents of the string.
5
2012-04-04 08:25
by Mark Tolonen
thanks mark.. i didn't knew it. - Sudip 2012-04-04 09:41
You're welcome! If the answer is useful up vote it or accept it - Mark Tolonen 2012-04-04 14:41


1

You can assign a regular Python string to a 100*c_char field:

class myS(ctypes.Structure):
    _fields_ = [("x", c_int),
         ("buffer", 100*c_char)]

s1 = myS(10, "foo")
s1.buffer = "bar"

If, however, you have a string buffer object, you can take its value:

buf = create_string_buffer(64) 
s1 = myS(10,buf.value)

Note also that

>>> type(create_string_buffer(100)) == 100*c_char
True
2012-04-04 08:23
by Janne Karila
thanks janne.. Its working when I put the actual string inside myS in s1 defn but why does it create problem when I put variable in its place. Both should have worked in the same way. - Sudip 2012-04-04 09:39
@Sudip Use buf.value to get the string - Janne Karila 2012-04-04 11:15
Ads