0

I'm trying to call c functions from python, I have the following code in c.

struct _returndata
{
    double* data;
    int row;
    int col;
};

int mlfAddmatrixW(struct _returndata* retArr)
{
    double data[] = {1,2,3,4,5,6,7,8,9} 
    retArr->row = 3;
    retArr->col = 3;        
    memcpy(retArr->data, data, 9*sizeof(double));            
    return  1;
}

This is my code in python:

class RETARRAY(Structure):
    _fields_= [("data", c_double*9),
              ("row", c_int),
            ("col", c_int)]

if __name__ == '__main__':      

    dll = CDLL("/home/robu/Documents/tmo_compile/libmatrix/distrib/libmatrixwrapper.so")    

    #Initializing the matrix 
    retArr = pointer(RETARRAY())

    for i in retArr.contents.data:
        print i;

    dll.mlfAddmatrixW(pointer(retArr))
    for i in retArr.contents.data:
        print i;

    print retArr.contents.row
    print retArr.contents.col

The content of the data has changed, but the col and row is still 0. How can I fix that? Is it possible to create a dynamic array in python , because in this case I created an array with 9 elements ("data", c_double*9),. I know the size of the array after I called mlfAddmatrixW function, the size of the array will be col*row.

Luke Woodward
  • 63,336
  • 16
  • 89
  • 104
Mokus
  • 10,174
  • 18
  • 80
  • 122

1 Answers1

2

You have a different struct in C and Python: one has a pointer to double, the other an array of doubles. Try something like:

NineDoubles = c_double * 9

class RETARRAY(Structure):
    _fields_= [("data", POINTER(c_double)),
              ("row", c_int),
              ("col", c_int)]

#Initializing the matrix 
data = NineDoubles()
retArr = RETARRAY()
retArr.data = data

dll.mlfAddmatrixW(pointer(retArr))
Janne Karila
  • 24,266
  • 6
  • 53
  • 94
  • The big problem, that I don't know the size of the array in python – Mokus Feb 10 '12 at 12:48
  • @iUngi Your C function expects that the array has already been allocated before calling. Can you change the C function? – Janne Karila Feb 10 '12 at 12:54
  • thanks for your help. Still I have 2 questions, if in c I return the address of the array `return retArr->data;` in python how can I reach the data of the array?. My other question is that the code above, in my question, if I change the row and col fields in c, don't have any effect in python that means I still 0 the value of this fields – Mokus Feb 10 '12 at 13:08
  • I fond the solution for the first question:http://stackoverflow.com/questions/5783761/ctypes-construct-pointer-from-arbitrary-integer – Mokus Feb 10 '12 at 13:46
  • Perhaps you have a struct alignment problem? i.e. different compiler settings for your C library than what was used to build ctypes. – Janne Karila Feb 10 '12 at 14:07