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

Problems when using the 'FOREIGN FUNCTION CALL INTERFACE'



Josef Fink writes:
 > Project: We are studying 'Information Science' at the 'University
 > of Konstanz' and are currently working on our graduate work. In this
 > work we aim to integrate a theorem prover written in 'C' in our 'CMU
 > Common Lisp-Environment' (-> version 16b on SPARCstation/Sun 4 with
 > 16/24 Mb memory) and in this term we intend to make exzessive use of
 > the 'FOREIGN FUNCTION CALL INTERFACE' (-> calling external
 > 'C'-Functions and accessing the environment of this 'C'-functions
 > after they have done their work). At the moment we try to evaluate
 > whether this aim of our work is feasable.

I have used the new alien interface and think it is very nice. Your
main problem is that load-foreign is broken in 16b. A new fixed
version is runored to be available soon from cmu. If you are in a
hurry I can probably make the core I am useing available by ftp. This
core is built from sources ftp from cmu sometime after the 16b release
with one small patch. I dont now if the source tree was consistent
then i ftp it but it seems to work for me.

 > Problem-Description: All our tests we have done so far, base on
 > your 'Step-by-Step Alien Example', presented in the 'CMU Common Lisp
 > User's Manual' (revised version of Technical Report CMU-CS-87-156 from
 > March 11, 1992).

The example from the manual does not work yet. Here is my first test
program for the alien interface in version 16. Based heavily on the
manual example.

C part. Called test.c

struct c_struct
{
  int x;
  char *s;
};
 
struct c_struct *c_function (i, s, r, a)
    int i;
    char *s;
    struct c_struct *r;
    int a[10];
{
  int j;
  struct c_struct *r2;
 
  printf("i = %d\n", i);
  printf("s = %s\n", s);
  printf("r->x = %d\n", r->x);
  printf("r->s = %s\n", r->s);
  for (j = 0; j < 10; j++) printf("a[%d] = %d.\n", j, a[j]);
  r2 = (struct c_struct *) malloc (sizeof(struct c_struct));
  r2->x = i + 5;
  r2->s = "A C string";
  return(r2);
};

lisp part;

 ;;; -*- Package: test-c-call -*-
(in-package "TEST-C-CALL")
(use-package "ALIEN")
(use-package "C-CALL")
 
;; This loads in the C object file with the function definition.
(eval-when (compile)
  (load-foreign "test.o"))
 
;;; Define the record c-struct in Lisp.
(def-alien-type nil
    (struct c-struct
            (x int)
            (s c-string)))
 
;;; Define the Lisp function interface to the C routine.  It returns a
;;; pointer to a record of type c-struct.  It accepts four parameters:
;;; i, an int; s, a pointer to a string; r, a pointer to a c-struct
;;; record; and a, a pointer to the array defined above.
 
(def-alien-routine c-function
    (* (struct c-struct))
  (i int)
  (s c-string)
  (r (* (struct c-struct)))
  (a (array int 10)))
 
;;; A function which sets up the parameters to the C function and
;;; actually calls it.
(defun call-cfun ()
  (with-alien ((ar (array int 10))
               (c-struct (struct c-struct)))
    (dotimes (i 10)                     ; Fill array.
      (setf (deref ar i) i))
    (setf (slot c-struct 'x) 20)
    (setf (slot c-struct 's) "A Lisp String")
    (with-alien ((res (* (struct c-struct))
                      (c-function 5 "Another Lisp String" (addr c-struct) ar)))
      (format t "Returned from C function.~%")
      (multiple-value-prog1
          (values (slot res 'x)
                  (slot res 's))))))


 > Problems:
 > 1.) function 'def-c-record' is not working as intended (-> 'Error
 > in EVAL::LEAF-VALUE: the function DEF-C-RECORD is undefined.')

I think DEF-C-RECORD is a relic from the old interface. Use
def-alien-type instead.

 > 2.) function 'def-alien-routine' is not working when called with a
 > list containing the LISP-name and the foreign name, like in the
 > example ('-> Error in function COMMON-LISP::%SET-FDEFINITION.
 > Malformed function name: "cfun".')

This is taken from my working code. Maybe the string and symbol got
mixed up ?

(def-alien-routine ("openfrm" c-openfrm)
    int
  (regname      c-string)
  (formatname   c-string)
  (filestat     int)
  (prgflag      int)
  (table        (* (struct c-table))))
 

 > 3.) function 'load-foreign' could not load the 'C' object file
 > after having successful executed the Shell-Script 'load-foreign.csh',
 > as demonstrated in your example (-> * (load-foreign "cfun.o"
 > :base-file "/pro/hoehle/lib/CMUlisp/lisp")

This is the killer bug in the default 16b for alien things. The fix
involves building a core from sources. So the easiest solution is to
wait for 16c (?) core. Or ask tell me if you are in a hurry and want a
short term solution.

 > Could you please help us in solving this problems (-> especially
 > the last problem) in the next days, because otherwise we have to
 > discard our intention as described above ?!

Well this should at least help somewhat.

 > With regards, Josef and Matthias.       

David Axmark
EMAIL:	davida@isil.detron.se
MAIL:	Detron HB, Petterslundsg 11 A, 753 28, UPPSALA, SWEDEN
PHONE:	+ (46) 18 - 11 07 80

(I can't spell in ANY language ...)