On Mon, Mar 29, 2010 at 5:12 PM, Ondrej Certik <[email protected]> wrote:
[...]
> should not be such a big deal to do this by hand, right? I have to try
> an example with double arrays. If I can wrap that, then I am fine.

Ok, so if I wrap things by hand, I can just write a simple C header
file like this:

void int_args_subr_(signed char *, short *, int *, long *, int *);
long int_args_func_(signed char *, short *, int *, long *);


then wrap it like this in Cython:



cdef extern from "arrayobject.h":

    ctypedef int intp

    ctypedef extern class numpy.ndarray [object PyArrayObject]:
        cdef char *data
        cdef int nd
        cdef intp *dimensions
        cdef intp *strides
        cdef int flags

cdef extern from "int_args.h":
    void int_args_subr_(signed char *, short *, int *, long *, int *)
    long int_args_func_(signed char *, short *, int *, long *)

def int_args_subr(signed char a, short b, int c, ndarray d, int n):
    int_args_subr_(&a, &b, &c, <long *>(d.data), &n)

def int_args_func(signed char a, short b, int c, long d):
    print "d before:", d
    r = int_args_func_(&a, &b, &c, &d)
    print "d after:", d
    return r



link it and it works just fine. Here is how to test it:



from numpy import array

from int_args import int_args_func, int_args_subr

def test_args1():
    assert int_args_func(1, 10, 100, 4) == 10

def test_args_arrays():
    a = array([5, 5, 5, 5], dtype="int64")
    int_args_subr(1, 10, 100, a, 4)
    assert list(a) == [111, 2, 8, -8]

    int_args_subr(1, 2, 3, a, 4)
    assert list(a) == [6, 2, 8, -8]

    int_args_subr(1, -2, 3, a, 4)
    assert list(a) == [2, 2, 8, -8]


If you want to play with the code, just do:

git clone git://github.com/certik/qsnake.git
cd qsnake/fortran_test/
cmake .
make
cd lib
py.test




So I am happy that it is actually really simple to wrap Fortran codes.
The only possible problems are argument ordering, "_" mangling, and
argument types (long vs int) across compilers and architectures and I
think the only robust solution is to either

1) generate the wrappers and do some checks with the current compilers/platform
2) do things by hand as I do, but write tests for all argument types
to make sure that the wrappers work

I guess fwrap will help with 1), but even 2) is fine for me, as I have
just couple functions to wrap, so it's not a big deal to update the C
header file and the Cython file by hand. At least I can nicely see
what is happening below the hood in case there are some problems.

Ondrej
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to