0

This is similar except I do not get a single value and instead segfault on [0] or .contents

How can I access the elements in 'array' from Python?

In C I have something like

#pragma pack(push, 1)
struct Data {
    int i;
    int *array;
};
#pragma pack(pop)

typedef struct {
    bool (* const get)   (struct Data*, const char *source);
    void (* const print) (struct Data*);
} DataFn;
extern DataFn const DATAFUNC;

In Python I have something like

class Data(ctypes.Structure):
    _fields_ = [
        ("i", ctypes.c_int),
        ("array",   ctypes.POINTER(ctypes.c_int))
    ]

class DATA_FN(ctypes.Structure):
    _fields_ = [
        ("get"   , ctypes.CFUNCTYPE(
                                          ctypes.c_bool,
                                          ctypes.POINTER(Data),
                                          ctypes.c_char_p)),
        ("print" , ctypes.CFUNCTYPE(None, 
                                          ctypes.POINTER(Data)))
    ]

From python I can do something like ..

    with open("xx0c.exx", "rb") as f:
        fdata = f.read()
        dfn.get(ctypes.byref(data),f fdata)
        dfn.print(ctypes.byref(data))
        print(data)
        print(data.i)                #7, correct
        #print(data.array.contents)  #segfault
        #print(data.array)           #segfault
        ptr = ctypes.pointer(data)
        print(ptr.contents.array[0]) #segfault

C function called from python will print .. which is correct

i = 7

array = 0x6ffff360034

array 0 = 20

array 1 = 27a40

array 2 = 127e20

array 3 = 128ae0

array 4 = 47e850

array 5 = 57ec30

array 6 = 580230

I can see the array in python isn't anywhere near the array in C.

Sample C code as asked. These are static, but they can be accessed through DATAFUNC. The C programs that use these are fine.

static bool getdata(struct Data *d, const char *filedata) {
    bool good = false;
    if (d != NULL && filedata != NULL) {
        d -> i       = (int32_t)filedata[0];
        d -> array   = (uint32_t*)(filedata + sizeof(int32_t));
        if ( d->i > 0 ) {
          good = true;
        }
    }
    return good;
}

static void printdata(struct Data *d) {
    if (d == NULL) {
        return;
    }
    printf("i = %i\n", d -> i);
    printf("array = %p\n", d -> array);
    unsigned int i;
    for (i = 0; i < d -> i; i++) {
        printf("array %i = %x\n", i, d -> array[i]);
    }
}
9
  • Can you please show your C code as well? It could be that the error is there. Commented Apr 24, 2018 at 13:31
  • I'm willing to, but as a warning it's working correctly for C programs that include it (it's also specific for a binary file format). Commented Apr 24, 2018 at 13:35
  • Are you reading the file inside a Python function? Because then the variable file will be local to that function, and its lifetime ends when the function end, making your pointer to the data invalid. Commented Apr 24, 2018 at 13:55
  • Yes it's read in the function. The portions posted here are technically together in the script, but segmented for formatting in the post & to show outputs for each line. Commented Apr 24, 2018 at 13:56
  • Then that's most likely your problem. Dynamically allocate memory to hold a copy of the data, and add functions to release this data when it's not needed anymore. Commented Apr 24, 2018 at 14:03

1 Answer 1

1

I've resolved the issue by adding pack to the python struct like as follows.

class Data(ctypes.Structure):
    _pack_   = 1
    _fields_ = [
        ("i", ctypes.c_int),
        ("array",   ctypes.POINTER(ctypes.c_int))
    ]

This fixes everything and gives the output of .. once a loop was added to iterate through arrays.

number of offsets = 7
offsets = 0x6ffff360034
offset 0 = 20
offset 1 = 27a40
offset 2 = 127e20
offset 3 = 128ae0
offset 4 = 47e850
offset 5 = 57ec30
offset 6 = 580230
<__main__.Data object at 0x6ffffd5f400>
7
<__main__.LP_c_int object at 0x6ffffd5f488>
0x20
0x27a40
0x127e20
0x128ae0
0x47e850
0x57ec30
0x580230
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.