pythoncshared-memorysysv-ipc

Shared memory between C and python


I want to share memory between a program in C and another in python.

The c program uses the following structure to define the data.

struct Memory_LaserFrontal {
        char Data[372]; // original data
        float Med[181]; // Measurements in [m]
        charD; // 'I': Invalid -- 'V': Valid
        charS; // 'L': Clean -- 'S': Dirty
        char LaserStatus[2];
        };

From python I have managed to read the variable in memory using sysv_ipc but they have no structure and is seen as a data array. How can I restructure them?

python code:

from time import sleep
import sysv_ipc

# Create shared memory object
memory = sysv_ipc.SharedMemory(1234)

# Read value from shared memory
memory_value = memory.read()

print (memory_value)
print (len(memory_value))
while True:
    memory_value = memory.read()
    print (float(memory_value[800]))
    sleep(0.1)

I have captured and printed the data in python, I have modified the sensor reading and the read data is also modified, confirming that the read data corresponds to the data in the sensor's shared memory. But without the proper structure y cant use the data.


Solution

  • I always like to leave the full source code of the problem solved so others can use it if they have a similar problem. thanks a lot all!

    from time import sleep
    import sysv_ipc
    import struct
    import array
    # Create shared memory object
    while True:
        memory = sysv_ipc.SharedMemory(1234)
    
        # Read value from shared memory
        memory_value = memory.read()
    
        #print (memory_value)
        #print (len(memory_value))
        # Get the initial char array - you can turn it into a string if you need to later.
        my_chars = array.array("b") # f for float, c for char etc.
    
        #my_chars.from_bytes(memory_value[:372]) # happens that 372 chars is 372 bytes.
        Data = my_chars.tolist() # Could be bytes list
        # advance to the member after Data
        end_of_Data = struct.calcsize("372c") 
    
        # get the length in bytes that 181 floats take up
        end_of_Med = struct.calcsize("181f") + end_of_Data
        # now we know where the floats are
        floats_as_bytes = memory_value[ end_of_Data : end_of_Med ]
        # unpack the remaining parts
        ( D, S, LaserStatus_1, LaserStatus_2 ) = struct.unpack( "cccc", memory_value[end_of_Med:] )
        print(len(floats_as_bytes)/4)
        a=[]
        for i in range(0,len(floats_as_bytes),4):
            a.append(struct.unpack('<f', floats_as_bytes[i:i+4]))
    
        print (a[0])
        sleep(0.1)