Previous: Porting Your Vaxima Package to Maxima Up: A Programmer's Guide for AKCL and MAXIMA Next: Loading C-coded Functions into CL or Maxima

Writing C code Directly in CL Files

Because AKCL generates an intermediate C file and then uses the C compiler to produce the object code, C code can be included inside lisp functions or files as literal lines. These lines are given in the form of lisp string constants and are treated as comments if the file is interpreted instead of compiled.

Here we give an example of defining a lisp function in C which interfaces between lisp and an f77 coded routine.


;;;;;;;;;;;;;;;;;;;;Inside lisp file ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; This is the C function which takes the lisp arrays and ;; pass the array bodies to f77

(defCfun "int capoly(ar, ai, di, zr, zi) object ar,ai,di,zr,zi;" 0 " double *apr, *api, *zeror, *zeroi; " " int *degrei; " " apr = (ar->lfa).lfa_self; " " api = (ai->lfa).lfa_self; " " zeror = (zr->lfa).lfa_self; " " zeroi = (zi->lfa).lfa_self; " " degrei = (di->fixa).fixa_self; " " return(alpoly_(apr,api,degrei,zeror,zeroi)); " )

;; Define lisp wrap-around function apolyrt for C function capoly

(defentry apolyrt (object object object object object) (int capoly))

The defCfun is the lisp mechanism to define a C level function. In this case the C function capoly is defined to take five arguments as lisp objects. This lisp wrapper for capoly is given by the defentry for apolyrt which takes five arguments created in lisp as follows

    ;; real and imag parts of poly coeffs in cr and ci
    (setq cr (make-array 101 :element-type 'long-float))
    (setq ci (make-array 101 :element-type 'long-float))
    ;; roots found by f77 routine will be in zr and zi
    (setq zr (make-array 100 :element-type 'long-float))
    (setq zi (make-array 100 :element-type 'long-float))
    ;; degree info in degrei
    (setq degrei (make-array 2 :element-type 'fixnum))
The five arrays are all lisp simple vector type and are allocated in consecutive memory allocations suitable for passing to C or f77 routines.

However, before C or f77 routines can manipulate these arrays, they must be converted to double or int pointers. In other words, we must have knowledge of the lisp object structure for simple vector of long-float or fixnum types to get access to the struct members that are the actual array pointers.

You see the C code for capoly does exactly that. All the structures for lisp objects are found in the header file <cmpinclude.h> which the lisp compiler uses to compile each lisp file.

Finally, the f77 function to be called is alpoly which is characterized by


       integer function alpoly(apr,api,degrei,zeror,zeroi)
       double precision apr(101),api(101),zeror(100),zeroi(100)
       integer degrei(2)

For more details of using C code inside AKCL, see the file kent/ppack/cqnullf.lsp, the C-coded Berlekamp factoring algorithm, for a substantial example. Also, refer to the common lisp report.

farrell@mcs.kent.edu