(top)  (memo)  (rss)
最近の Common Lisp 界では FFI の定番といえば CFFI のようです. UFFI のプロジェクトも多いですが. 昔書いたドキュメントの例 を CFFI で試してみました.
#include <stdio.h>
int float_to_bits (float f) {
return *((int*)&f);
}
int double_to_bits_hi (double f) {
return ((int*)&f)[0];
}
int double_to_bits_lo (double f) {
return ((int*)&f)[1];
}
float bits_to_float (int i) {
return *((float*)&i);
}
double bits_to_double (int hi, int lo) {
int v[2];
v[0] = hi;
v[1] = lo;
return *((double*)v);
}
上記のような C のコードから
gcc -Wall -fPIC -shared -o float.so float.c
として共有ライブラリ float.so を作成します.これへのインターフェース は以下の通り.
(defpackage :example.cffi (:use #:cl #:cffi)
(:export #:float-to-bits #:double-to-bits #:bits-to-float #:bits-to-double #:test))
(in-package :example.cffi)
(define-foreign-library libfloat
(:unix"float.so")
(:windows "float.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 'libfloat))
(defcfun ("float_to_bits" float-to-bits) :int
(f :float))
(defcfun ("double_to_bits_hi" double-to-bits-hi) :int
(f :double))
(defcfun ("double_to_bits_lo" double-to-bits-lo) :int
(f :double))
(defcfun ("bits_to_float" bits-to-float) :float
(i :int))
(defcfun ("bits_to_double" bits-to-double) :double
(hi :int)
(lo :int))
(defun double-to-bits (d)
(values (double-to-bits-hi d) (double-to-bits-lo d)))
実際にはデフォルトで _ と - の変換は行なわれるため,defcfun で の Lisp 側の関数名定義は冗長でした.
posted: 2006/04/16 04:32 | permanent link to this entry | Tags: LISP