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

foreign function interface

I'm trying to interface to a library of C routines, but having
difficulties. Let me describe what is happening.

The routines are meant to be FORTRAN compatible, so every arguments are
passed by reference. This poses a problem, in particular, when passing a
short by address (the same is true for array of floats, array of short,
etc.). The foreign function interface in Franz Allegro CL doesn't seem to
provide a way to pass in such a type, or I haven't been able to find it in
the documentation. The problem is that the C routine doesn't see the
correct LISP value. What I came up with is the following kludge to solve
the problem (for the case of short so far).

First, some C definitions:

  int coerced_short;

  long int coerce_2_short(x)
    int x;
    coerced_short = (short)(*x);
    return (long int)(&coerced_short);

What I do is pass in a (LISP) integer to the above function, which returns
the address of the short. I can then pass this address to the routine that
expects a short to be passed by address. Of course, the corresponding
parameter was declared using `defforeign' to be of type fixnum and passed
by value. However, this approach appears dangerous -- I would feel better
if the foreign function interface provided a way to explicitly pass in a C
pointer (Lucid Common Lisp provides a mechanism to do this). It would be
even better if foreign function interface provided a way to pass in a short
by address explicitly.

My impression so far of the foreign function interface is that it appears
to be geared more towards C routines interfacing to LISP than vice versa.

Another unrelated encounter with `defforeign' that I needed to solve was in
passing a fixnum by address. It was cumbersome to have to create an array
of size 1 to get a value back from C each time, so what I ended up doing
was writing a macro that would define an external C routine in the
following manner:

  (defc foo (*integer))

The * indicates that the argument is being passed by address. Now, if I
called (foo x) with x bound to 3, this binding will change when the
function returns. By the way, (foo 3) will have no effect. This seems
unconventional to LISP style of programming; nevertheless, the foreign
function interface already does this by changing the value of a symbol of
other simple types like float. I don't understand why this wasn't extended
to include fixnum.

I would greatly appreciate any Allegro Common Lisp experts' comments or
suggestions. Thanks in advance.

Ik S. Yoo
Lockheed AI Center
Orgn. 96-20, Bldg. 259
3251 Hanover St.
Palo Alto, CA  94304-1191
(415) 354-5584