cast a structure in python
Question: i am using ctypes to read some data from an external Database.

this data is written in struct. the problem is, that the recieved Data could
have different results. for bettern understanding: i have created two
structures:

    
    
    class BEAM(Structure):
        _fields_ = [
            ('NR', c_ulong),
            ("NODE1", c_ulong),
            ("NODE2", c_ulong),
            ("NP", c_ulong),
            ("DL", c_float),
            ("foo", c_ulong),
            ("foobar", c_ulong),
            ("bar", c_ulong),
            ("barfoo", c_ulong)
        ]
    
    class DUMMY(Structure):
        _fields_ = [
            ('ID', c_ulong),
            ("NODE1", c_ulong),
            ("NODE2", c_ulong),
            ("NP", c_ulong),
            ("DL", c_ulong),
            ("foo", c_ulong),
            ("foobar", c_ulong),
            ("bar", c_ulong),
            ("barfoo", c_ulong)
        ]
    

the difference between this structs is the u_long type in "DL"... in DUMMY it
is u_long, in BEAM it's u_float.

after reading the datbase i get into DL = 1056964624 but in float is should be
0.5

my question is how can i cast the DUMMY into BEAM.

i have tried `BEAMRecord = cast(Record, POINTER(BEAMRecord))` but there is an
error called TypeError: must be a ctypes type

here is my code:

    
    
    '''
    Structure for DataLength
    '''
    class Len(Structure):
        _fields_ = [
            ('buffer', c_int)
        ]
    
    
    SLNRecord = element.SLN()
    BEAMRecord = element.BEAM()
    
    Record = element.DUMMY()
    RecLen = Len()
    
    sofistik = cdll.LoadLibrary("cdb_w30_x64.dll")
    
    py_sof_cdb_init = sofistik.sof_cdb_init
    py_sof_cdb_close = sofistik.sof_cdb_close
    py_sof_cdb_get = sofistik.sof_cdb_get
    
    py_sof_cdb_get.restype = c_int
    
    Index = py_sof_cdb_init("system.cdb", 99)
    
    pos = c_int(0)
    
    while True:
        RecLen.buffer = sizeof(Record)
    
        ie = py_sof_cdb_get(Index, 100, 0, byref(Record), byref(RecLen), pos)
    
        pos.value += 1
    
        if ie > 1:
            break
    
        if Record.ID > 0:
            BEAMRecord = cast(Record, POINTER(BEAMRecord))
            print BEAMRecord
    
    py_sof_cdb_close(0)
    
    exit()
    

thanks for helping

* * *

**Solution:**

by reading [this thread](http://stackoverflow.com/questions/1825715/how-to-
pack-and-unpack-using-ctypes-structure-str?rq=1) i modified @Mr Temp question

i created a `BEAMRecordPointer = POINTER(element.BEAM)` and `BEAMRecord =
cast(Record, POINTER(BEAMRecord))` i rewrite to `BAR = cast(byref(Record),
BEAMRecordPointer).contents` so the solution looks like this

    
    
    if Record.ID > 0:
            BAR = cast(byref(Record), BEAMRecordPointer).contents
            print BAR
    

I'm doing it wrong?

* * *

**Update 1**

@eryksun has a really good shothand for the cast() function. Thank you.


Answer: You could just load the structure into a `Union`, then access it how you need
to:

    
    
    from ctypes import *
    
    class BEAM(Structure):
        _fields_ = [('NR', c_ulong),
                    ("NODE1", c_ulong),
                    ("NODE2", c_ulong),
                    ("NP", c_ulong),
                    ("DL", c_float),
                    ("foo", c_ulong),
                    ("foobar", c_ulong),
                    ("bar", c_ulong),
                    ("barfoo", c_ulong)]
    
    class DUMMY(Structure):
        _fields_ = [('ID', c_ulong),
                    ("NODE1", c_ulong),
                    ("NODE2", c_ulong),
                    ("NP", c_ulong),
                    ("DL", c_ulong),
                    ("foo", c_ulong),
                    ("foobar", c_ulong),
                    ("bar", c_ulong),
                    ("barfoo", c_ulong)]
    
    class Both(Union):
        _fields_ = [('Beam',BEAM),('Dummy',DUMMY)]
    
    x = Both()
    x.Dummy.DL = 1056964624
    print(x.Beam.DL)
    

Output:

    
    
    0.5000009536743164
    

Or more simply:

    
    
    from ctypes import *
    
    class DL(Union):
        _fields_ = [('DUMMY',c_ulong),('BEAM',c_float)]
    
    class Hybrid(Structure):
        _fields_ = [('NR', c_ulong),
                    ("NODE1", c_ulong),
                    ("NODE2", c_ulong),
                    ("NP", c_ulong),
                    ("DL", DL),
                    ("foo", c_ulong),
                    ("foobar", c_ulong),
                    ("bar", c_ulong),
                    ("barfoo", c_ulong)]
    
    x = Hybrid()
    x.DL.DUMMY = 1056964624
    print(x.DL.BEAM)
    

(same output)

