Вопрос

I have a C library:

smart_string.h:

typedef struct SmartString {
    unsigned string_len;
    unsigned alloc_len;
    char *str;
    char *str_terminator;

} SmartString;

SmartString *SmartString_new(char *str);
... definitions of more functions ...

The implementation is found in a file named smart_string.c.

I need a guide for running the SmartString_new() function and accessing the fields of the returned struct-pointer.

Can anyone please show me how to do it?

Thanks!

Это было полезно?

Решение

Answering myself and sharing the knowledge with you:

First, need to create a shared library from the C file:

gcc -shared -fpic smart_string.c -o SmartString.so

Then, use the following Python code (see comments for explanation about each done action):

Note: char*, as appears in the above API is a C editable string, while const char* is a read-only string. Because the C API requires char* and not const char*, we have to pass to it a mutable string, so it can be edited by the C code. Python strings are immutable by default. Here we use therefore, the create_string_buffer() function

python_smart_string.py:

import ctypes
from ctypes import *

# Defining the python type that represents the C SmartString
# It must extend the 'Structure' class
# Structure, c_uint, c_char_p, etc. were imported from ctypes
class SmartString(Structure):
    _fields_=[("string_len",c_uint),
              ("alloc_len",c_uint),
              ("str",c_char_p),
              ("str_terminator", c_char_p)]


# Loading the C shared lib I've just compiled
smartstring_lib = ctypes.CDLL('SmartString.so')

# Defining pointer to the SmartString_new() function
SmartString_new = smartstring_lib.SmartString_new

# Declaring the function return type - a pointer to a SmartString object - just like in the C code
SmartString_new.restype = POINTER(SmartString)

# Declaring list of parameter types. In this case, the list contains only one item,
# as the function has only one parameter
SmartString_new.argtypes = [c_char_p]

# Calling the SmartString_new() function. Expecting to get a pointer to SmartString object into 'my_str'
# The API requires a MUTABLE string, so create_string_buffer() is used here
# The reference to this string is not saved, as I don't care if it is modified by the C code
my_str = SmartString_new(create_string_buffer('my nice string'))

# Printing fields of the dereferenced returned value (dereferencing is done using '.contents')
print my_str.contents.string_len
print my_str.contents.alloc_len
print my_str.contents.str
print my_str.contents.str_terminator
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top