LISPUSER

LISPMEMOLisp is a programmable programming language. -- John Foderaro

(top)  (memo)  (rss)

CFFI 入門 (1)

最近の 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

(top)  (memo)  (rss)