From octave-maintainers-request at bevo dot che dot wisc dot edu Mon Dec 16 10:41:59 2002 Subject: Re: foreign function interface From: Andy Adler To: Paul Kienzle cc: octave-maintainers at bevo dot che dot wisc dot edu Date: Mon, 16 Dec 2002 11:40:02 -0500 (EST) This is a great idea. The best similar concept I'm aware of is Perl's Win32::API. It is used like this: use Win32::API; $GetPID = new Win32::API("kernel32", "GetCurrentProcessId", '', 'N'); $PID = $GetPID->Call(); This allows direct access to windows dll's. The only tricky part is packing data into the appropriate structs for each dll to use. In order to offer a similar function from octave, we would need something like perl's "pack" function. I was thinking (for other reasons) that a we need a "sread" and "swrite" analgous to "fread" and "fwrite". These functions would read and write to a string (or other byte data vector) rather than to a file. Andy On Sat, 14 Dec 2002, Paul Kienzle wrote: > 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 > pkienzle at users dot sf dot net > >