Health check: Am I using ctypes correctly?

This is a follow up on Getting the destination memory address of a memory range via python / ctypes

I'm finally so far away that I can start testing, but I'm not sure if I'm doing it right as addresses are addressed to addresses in lists of structures containing structures. And in C they are calculated using macros.

I think I did it right, but I'm not sure if I set the arguments correctly. And thus, you will love your opinion.

Note. The test function of the objective function has the following snapshot:

void function( ulong startAddress, ulong endAddress, ulong curAddress, int nofPaddingElements )

      

Note2: I have to test this on real hardware, so I haven't implemented many shortcuts at the moment.

I am not allowed to post the real code here, so I will give the pseudo code as much as possible.

1) definition of the type buffer-struct. Contains pointers to other structures, not as a pointer but as ulongs.

class My_Buffer_t( ctypes.Structure ):
    _fields_ = [
       ( "some_bool" , ctypes.c_bool ),
       ( "head",       ctypes.c_ulong ),
       ( "tail",       ctypes.c_ulong ),
       ( "headSize",   ctypes.c_ulong ),
       ( "dataSize",   ctypes.c_ulong ) ]

      

The main data structure exists from two other structures

class Struct1( ctypes.Structure ):
    _fields_ = [
       ( "entry1", Struct2 ),
       ( "entry2", Struct3 ) ]

class Struct2( ctypes.Structure ):
# Only contains basic types
    _fields_ = [
       ( "data1", ctypes.c_int ),
       ...
       ( "datax", cyptes.c_ushort ) ]

class Struct3( ctypes.Structure ):
# Mix of basic types and 1 other structure
    _fields_ = [
       ( "data1", ctypes.c_double ),
       ...
       ( "datax", cyptes.c_int ),

       ( "timestamp_data1", TimeStampStruct ),
       ...
       ( "timestamp_datax", TimeStampStruct ) ]

class TimeStampStruct( ctypes.Structure ):
    _fields_ = [
       ( "field1", ctypes.c_ulong ),
       ( "field2", ctypes.c_ulong ) ]

      

List creation function (I basically copied the C function):

def create_list( bufsize, buffer ):
    # buffer is of type My_Buffer_t

    # It actually creates some shared memory where headSize also needed to be divided by 
    # ctypes.sizeof( ctypes.c_size_t )
    # And afterwards again was multiplied by ctypes.sizeof( ctypes.c_size_t )
    # But since the shared-memory is not of importance for the function-under test I left
    # that part out.
    headSize = (ctypes.c_size_t )( ( ctypes.sizeof(
            My_Buffer_t ) + ctypes.sizeof( ctypes.c_size_t ) - 1 ) )
    dataSize = ( ctypes.c_size_t ) ( ( bufsize + ctypes.sizeof(
            ctypes.c_size_t ) - 1 ) / ctypes.sizeof( ctypes.c_size_t ) )

    buffer.some_bool = True
    buffer.head      = 0
    buffer.tail      = 0
    buffer.headSize  = (ctypes.c_ulong)(headSize)
    buffer.dataSize  = (ctypes.c_ulong)(dataSize)

    return buffer

      

Macro which I translated to python function (again I am as close to C code as possible)

def get_data_address( list_ptr ):
    # list_ptr is of type My_buffer_t, but the data is of type Struct1
    return( ( ctypes.c_ulong )( ctypes.c_void_p )( ctypes.c_byte )(
            list_ptr ) + ( list_ptr.headSize ) )

      

How it all comes together

max_entries = 100000
list_size   = max_entries * ctypes.sizeof( Struct1 )

# First argtype use:
create_list.argtypes = ( ctypes.c_ulong, My_Buffer_t )
list_ptr             = create_list( list_size, My_Buffer_t() )

# Determine the addresses (2nd use of argtypes):
get_data_address.argtypes = ( My_Buffer_t )
startAddress              = get_data_address( list_ptr )
endAddress                = startAddress + list_size
curAddress                = startAddress
nofPaddingElements        = ctypes.sizeof( struct3 ) / ctypes.sizeof( ctypes.c_int )

# Call the SUT (final use of argtypes)
function.argtypes = ( ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_int )
function( startAddress, endAddress, curAddress, nofPaddingElements )

# rest of the test is simple basic python

      

Am I doing something wrong here or maybe too hard? Or am I doing it right?

+3


source to share





All Articles