octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

foreign function interface


From: Paul Kienzle
Subject: foreign function interface
Date: Sat, 14 Dec 2002 01:29:58 -0500

Hi, all.

I've been trying to think of ways to lower the barrier for contributions to
octave. In particular, there are a lot of prefectly good libraries out there
that people could call if it were easy to call them. While oct-file
programming is much easier than mex-file programming, I believe we can do
even better than that.  I would like for us to be able to directly call
sharable object code from a script without writing a DEFUN_DLD wrapper.

The technique is called variously a foreign function interface or a native
call interface.  Given a native type signature (e.g., double sin(double)) we
should be able to have a definition ffi("libm","sin","dd","Nsin") which
defines the octave function Nsin, which you could then call from octave as x
= Nsin(y).  For extra convenience it would be nice to automatically apply
scalar functions like this element-wise on a vector.  Functions like sqrt
would be a problem, but these could be handled easily enough from a script
such as: function x=sqrt(y), x = Nsqrt(abs(y)); x(y<0) *= 1i; end

There are three approaches that I've encountered for doing this:

(1) fortran style:  everything must be a pointer.  This is less than ideal
since a lot of functions don't operate on pointers, so users would have to
wrap the library functions with functions that accept pointers.  This is
still easier than figuring out how to use the octave_value properly.  R
seems to do this.

(2) predefined type signatures: predefine functions for all the possible
type signatures that you might want to call.  In principle you could write
special functions for each possible type signature.  E.g., ffi(...,"dd",...)
would call a function like dd_chain(double (*f)(double),octave_value &ov)
which internally would be defined like:
octave_value dd_chain(double (*f)(double), octave_value &ov)
    Matrix in(ov.matrix_value());
    Matrix out(ov.rows(),ov.columns());
    const double *pin = in.data();
    double *pout = out.fortran_vec();
    for (int i=0; i < in.length(); i++) { pout[i] = (*f)(pin[i]); }
    return octave_value(out);
The problem with this approach is that the various combinations of
void/character/integer/float/double/complex, and pointers thereto leads to a
small
explosion in the number of functions.  I believe Perl does this with its
native call interface (or it will in Perl6 whenever that is released.)

(3) compiler-like call.  Build a stackframe, jump to the function and await
the return.  This is the ideal way since it is not limited in terms of the
number or type of paramters, but it is very machine dependent.  libffi
provides this for a number of platforms.

Does anyone have experience in this sort of thing? Does it sound like a
worthwhile venture?

Paul Kienzle
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]