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?
source to share
No one has answered this question yet
See similar questions:
or similar: