Verrazano

Verrazano
http://common-lisp.net/project/fetter/
swigよりも賢くcffiインターフェイスを生成してくれるtool

install

sudo apt-get install darcs cl-s-xml cl-ppcre
#sudo apt-get install cl-parse-number #donot have ubuntu?

cd SRCDIR
darcs get --partial http://common-lisp.net/project/alexandria/darcs/alexandria
sudo mv alexandria /usr/share/common-lisp/source/
cd /usr/share/common-lisp/systems; sudo ln -s ../source/alexandria/alexandria.asd ./
cd SRCDIR
darcs get --partial http://common-lisp.net/project/fetter/darcs/verrazano/
sudo mv verrazano /usr/share/common-lisp/source/
cd /usr/share/common-lisp/systems; sudo ln -s ../source/verrazano/verrazano.asd ./
cd SRCDIR
sudo sbcl

(require :asdf-install)
(asdf-install:install :iterate)
(asdf-install:install :trivial-shell)
;(asdf-install:install :parse-number)
;(asdf-install "http://common-lisp.net/project/asdf-packaging/parse-number-latest.tar.gz")

インストールが成功したかtest
(asdf:oos 'asdf:load-op :alexandria)
(asdf:oos 'asdf:load-op :verrazano)

usage

ダウンロードしたファイルのディレクトリ verrazano/tests/vfun にあるsample codeの通りにすればwrapperを自動生成してくれる。例えば以下のようなc++コードをlispから呼べるようになる.

//vfun.h 
typedef char char_array[255];
#define MY_VAR 200
#define MY_VAR2 0x100
void frob_array(char_array ar);
class baser{
        public:
                baser(int value);
                virtual int get_value();
        private:
                int myValue;};
class base{
        public:
                base(int value);
                virtual ~base();
                virtual int get_value();
                virtual int set_value(int val);
                virtual int get_id();
        private:
                int myValue;};
class derived :public base{
        public:
                derived(int value);
                virtual int get_id();};

これを以下のように呼んでくれる

(require 'asdf)
(asdf:operate 'asdf:load-op :cffi)
(cffi:load-foreign-library "libvfun.so")
(load (merge-pathnames "../testsuite/vfun/vfun-cffi-bindings.lisp"
                       (asdf:component-pathname (asdf:find-system :verrazano))))
(defpackage :vfun-test
  (:use :common-lisp :vfun-cffi-bindings))
(in-package :vfun-test)
(let ((pr (baser-new-1 3))
      (pb (base-new-1 5))
      (pd (derived-new-1 7)))
  (format t "~A ~A ~A~%" 
          (baser-get-value pr)
          (base-get-value pb)
          (base-get-value pd)))

this make generreted code usr/share/common-lisp/source/verrazano/foo/foo-cffi-...lisp

もっと複雑なものできるのか試すために画像処理library BIASに適用してみよう。以下でwrapperを生成してくれる.

cd BIAS-2.5.0/Geometry
sudo mkdir /usr/share/common-lisp/source/verrazano/../testsuite
sudo mkdir /usr/share/common-lisp/source/verrazano/../testsuite/vfun
sudo sbcl

(in-package :cl-user)
(eval-when (:compile-toplevel :load-toplevel :execute)
  (require :asdf))
(eval-when (:compile-toplevel :load-toplevel :execute)
  (asdf:operate 'asdf:load-op :verrazano))
(in-package :verrazano-user)
(generate-binding
 (make-configuration :vfun-cffi-bindings
                     ;'("vfun.h")
		     '("PMatrix.hh")
                     :working-directory (verrazano::system-relative-pathname
                                         :verrazano "../testsuite/vfun/")
                     :gccxml-flags "-I. -I..")
 :cffi)
(in-package :cl-user)
(quit)

以下のエラーで止まる

GCC-XML version 0.7.0
$ gccxml -I. -I.. -fxml="//tmp/465vzntemp.xml" "//tmp/465vzntemp.cpp" 
$ gccxml -I. -I.. --preprocess -dDI "//tmp/465vzntemp.cpp" >"//tmp/465vzntemp.mac"

debugger invoked on a SIMPLE-ERROR in thread #:
  There is no applicable method for the generic function
    #
  when called with arguments
    (#).