Specify the return type for a ctypes call (in python) to a fortran function that returns an array of doubles
Question: I'm trying to use the ctypes module to call, from within a python program, a
(fortran) library of linear algebra routines that I have written. I have
successfully imported the library and can call my _subroutines_ and functions
that return a single value. My problem is calling functions that return an
array of doubles. I can't figure out how to specify the return type. As a
result, I get segfaults whenever I call a function like that.

Here's a minimum working example, a routine to take the cross product between
two 3-vectors:

    
    
    !****************************************************************************************
    ! Given vectors a and b, c = a x b
    function cross_product(a,b)
    real(dp) a(3), b(3), cross_product(3)
    
    cross_product = (/a(2)*b(3) - a(3)*b(2), &
                      a(3)*b(1) - a(1)*b(3), &
                      a(1)*b(2) - a(2)*b(1)/)
    end function cross_product
    

Here's my python script:

    
    
    #!/usr/bin/python
    from ctypes import byref, cdll, c_double
    testlib =  cdll.LoadLibrary('/Users/hart/codes/celib/trunk/libutils.so')
    cross = testlib.vector_matrix_utilities_mp_cross_product_
    
    a = (c_double * 3)()
    b = (c_double * 3)()
    a[0] = c_double(0.0)
    a[1] = c_double(1.0)
    a[2] = c_double(2.0)
    b[0] = c_double(1.0)
    b[1] = c_double(3.0)
    b[2] = c_double(2.0)
    
    print a,b
    cross.restype = c_double * 3
    print cross.restype
    print cross(byref(a),byref(b))
    

And here's the output:

    
    
    goku:~/python/ctypes> ./test_example.py 
    <__main__.c_double_Array_3 object at 0x10399b710> <__main__.c_double_Array_3 object at 0x10399b7a0>
    <class '__main__.c_double_Array_3'>
    Segmentation fault: 11
    goku:~/python/ctypes>
    

I've tried different permutations for the line "cross.restype = ..." but I
can't figure out what should actually go there. Thanks for reading this
question. --Gus


Answer: The compiler may return a pointer to the array, or the array descriptor... So,
when mixing languages, you should always use `bind(C)` except when the wrapper
specifically supports Fortran. And (not surprisingly) `bind(C)` functions
cannot return arrays. You could theoretically allocate the array and return
`type(c_ptr)` to it, but how to dealocate it after the use?

So my suggestion is to use a subroutine.

