5

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!

0

1 Answer 1

8

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
Sign up to request clarification or add additional context in comments.

1 Comment

specify SmartString_new.argtypes = [c_char_p]. You might need to keep a reference to create_string_buffer(). my_str[0] is another way to dereference a pointer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.