1

I'm having a C function that returns a pointer to an struct:

struct iperf_test *
iperf_new_test()
{
    struct iperf_test *test;

    test = (struct iperf_test *) malloc(sizeof(struct iperf_test));
    ...
    return test;
}

This function is called from Python in the following way:

self.lib = cdll.LoadLibrary("lib.so")
self._test = self.lib.iperf_new_test()

The struct has some values such as:

struct iperf_test
{
    int       server_port;
    int       bind_port; 
};

The examples I see on the internet shows that I need to use a function that receives a pointer to alter the values, for example in python:

self.lib.iperf_set_test_server_port(self._test, int(port))

And in C:

void
iperf_set_test_server_port(struct iperf_test *ipt, int srv_port)
{
    ipt->server_port = srv_port;
}

Is there a way to change the value bind_port directly without using a C function?

1
  • You can recreate the struct definition in Python as class derived from ctypes.Structure, create a ctypes.POINTER type of this class and set this as restype of the function. Then you can change the value directly. Commented Jan 5, 2018 at 23:23

1 Answer 1

3

Yes. This is why ctypes supports defining your own structs, and defining prototypes for functions.

You'd need to make a Python level definition of your structure, e.g.:

from ctypes import Structure, c_int, POINTER

class iperf_test(Structure):
    _fields_ = [("server_port", c_int),
                ("bind_port", c_int)]

Then, before calling your C function, you set its restype correctly:

# Load library as normal
self.lib = cdll.LoadLibrary("lib.so")
# New, so Python knows how to interpret result
self.lib.iperf_new_test.restype = POINTER(iperf_test)
# Call, and Python returns pointer to Python definition of struct
self._test = self.lib.iperf_new_test()

Now you can use it by dereferencing (done with [0] since Python lacks a * pointer dereference operator) and setting attributes on the dereferenced struct directly:

self._test[0].bind_port = new_bind_port
Sign up to request clarification or add additional context in comments.

2 Comments

Is possible to partially recreate the struct? for example, the struct has a lot of object types (some are custom created), that could be difficult to convert to python.
@h3ct0r: If you only ever use single instances of the struct (no arrays), and only use pointers to it allocated in C (no copying), you can usually just define the first fields and stop when you reach the ones you don't care about. Alternatively (more safely), you can define trivial placeholder attributes of the correct size (e.g. for the pointers you don't care about the contents of, just declare the field as c_void_p, a void pointer); doing so makes it safer for use with arrays and the like. But if you need full control of all attributes, you must define all types involved.

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.