use cffi from maxima

cffiを使ってmaximaからcのプログラムを呼ぶ. CFFI入門で使われている例ではfloatを使っているがmaximaではfloatを使えないのでintとdoubleを使った以下のsq.cを呼ぶ

//sq.c
#include <stdio.h>
int int_sq (int i) {
  return i*i;
}
double double_sq (double d) {
  return d*d;
}
//can not use float in maxima
/*
float float_sq (float f) {
  return f*f;
}
*/

sq.soを作る

gcc -Wall -fPIC -shared -o sq.so sq.c

ubuntuのパッケージのmaximaはcffiを使えないので使えるようにコンパイルしなおす

    1. download maxima-5.14.0.tar.gz from http://maxima.sourceforge.net/
    2. tar zxf maxima-5.14.0.tar.gz; cd maxima-5.14.0
    3. LANG=C ./configure --enable-clisp --enable-sbcl --with-cffi --with-asdf --with-default-lisp=clisp
    4. LANG=C make
    5. LANG=C make check
    6. LANG=C checkinstall

コンパイルとinstallが終わったらmaximaを起動して以下をする
$maxima
to_lisp();

(asdf:oos 'asdf:load-op :cffi)
(defpackage :example.cffi (:use #:cl #:cffi)
   (:export #:int-sq #:double-sq ))
(in-package :example.cffi)
(define-foreign-library libsq
  (:unix"sq.so")
  (:windows "sq.dll"))
(defun load-directory ()
  (let ((here #.(or *compile-file-truename* *load-truename*)))
    (make-pathname :directory (pathname-directory here))))
(let ((*foreign-library-directories* (list (load-directory))))
  (load-foreign-library 'libsq))
(defcfun ("int_sq" int-sq) :int
  (i :int))
(defcfun ("double_sq" double-sq) :double
  (d :double))

以上で準備ができた.使い方は以下のよう
> (int-sq 3)
9
> (double-sq 3.9)
15.209999999999999

これでcで書かれた数値計算プログラムをmaximaから使うことができる

lispから直接doubleを使う場合は
(double-sq 3.9d0)