How do I access values stored in an array inside a C struct returned to Python via ctypes?

KBriggs

I am trying to learn to use ctypes to populate a linked list of C structs and return the head of the list to Python for post processing. To do that, I have a simple C struct, defined like so:

struct Checkpoint
{
     double *state;
     struct Checkpoint *next;
};
typedef struct Checkpoint checkpoint;

And I have a simple matching Python 3 class defined like so:

class Checkpoint(ct.Structure):
    pass
Checkpoint._fields_ = [('state', ct.POINTER(ct.c_double)),
                       ('next', ct.POINTER(Checkpoint))]

After calling the C code via ctypes to populate a few examples of this structure, I try to print the values in the state array on the python side.

def main():
    # Load the shared library into c types.
    libc = ct.CDLL("./structs.so")
    entry = wrap_function(libc, 'pymain', ct.POINTER(Checkpoint), None)
    get_state = wrap_function(libc, 'get_state', ct.POINTER(ct.c_double), [ct.POINTER(Checkpoint)])
    get_next = wrap_function(libc, 'get_next', ct.POINTER(Checkpoint), [ct.POINTER(Checkpoint)])
    start = entry()
    print(get_state(start).contents);
    start = get_next(start)
    print(get_state(start).contents);

The get_state and get_next functions are as follows:

double *get_state(checkpoint *current)
{
    return current->state;
}

checkpoint *get_next(checkpoint *current)
{
    return current->next;
}

These functions are returning a reference to the correct memory, but I am having trouble accessing anything beyond the first element of the arrays in the structs so defined.

Two questions:

  1. Do I need the get_state and get_next functions, or can I access those parameters directly in Python without doing a call back to C after my structures are defined and populated? If so, how?

  2. My main function in python works to populate the structures as I want them, but only the first value of the state array is printed by the print calls. How to I access the rest of the values in the array?

Jacob Boertjes

To answer your first question, I believe the get_state and get_next are not necessary, as you can access the fields of Checkpoint directly

start = entry()
state = start.contents.state
next = start.contents.next

As for the second question, in the case of pointers, .contents will provide the value stored at the pointer's memory address. This means it will only print the first item in the array instead of the entire array. To print the entire array, you must loop through it, printing each element. When only using the pointer, the array's size is unknown, so the first step is to store this count. I think the Checkpoint struct would be a good location.

struct Checkpoint
{
     double *state;
     int state_len;
     struct Checkpoint *next;
};
typedef struct Checkpoint checkpoint;

Then, you'll need to update the python class

class Checkpoint(ct.Structure):
    pass
Checkpoint._fields_ = [('state', ct.POINTER(ct.c_double)),
                       ('state_len', ct.c_int),
                       ('next', ct.POINTER(Checkpoint))]

I'm not sure where your state array is populated, but you'll need to update the state_len wherever you add elements.

Once this is done, you should be able to print the contents using a loop like the following:

start = entry()
for i in range(start.contents.state_len):
    print(start.contents.state[i])

Sources: https://docs.python.org/3/library/ctypes.html#type-conversions

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How do I access the index of items inside an array that is inside a dictionary?

Read an ARRAY from a STRUCT returned by a stored procedure

How do I convert a Python list into a C array by using ctypes?

How do I access the values inside a MATLAB array using Cgo?

Python ctypes definition for c struct

Python Ctypes: Convert returned C array to python list, WITHOUT numpy

How do I access a struct nested inside a struct

Python `ctypes` - How to copy buffer returned by C function into a bytearray

How to access values returned by a Stored Procedure in Code Behind

C to Python via Ctypes - Wrapping Struct of Function Pointers to Static Functions

Update values of a struct pointer in ctypes python without using a C function

How do I access an 'Array' inside an Array using Angular?

How do I access an index of a pointer inside of an array in C?

In Powershell, How do I get the Values out of an array returned by an object?

How do I access a typedef struct pointer to an internal object with ctypes?

how do I assign a value to a struct array inside a struct in c?

in Coldfusion how do I add a 'column' to the struct inside an array?

how do i get values stored in struct?

Access np.array in ctypes struct

How do I access the values in an object inside a HashMap

How do I access an alias declared inside struct/class scope?

How do I access data in an array that was returned by a function?

How do I access the values in the function stored in the PSObject?

ctypes: How to access array of structure returned by function?

how do i change values of a global struct inside main/another function in c?

How to access specific values inside a list that are stored in a idx variable? (python)

How do I optimize array access in python?

How do i read the values of a returned pointer from ctypes?

How do I access nested elements inside a json array in python