Posted at

uffiかcffiか

More than 5 years have passed since last update.

釈迦に説法になりそうだなーと思いながら

風邪で寝こんでてたら改めて書いたり考えたりできなさそうな感じで申し訳ないなな感じに…

きがついたら直します。全体的に。


そもそもffiとは?

http://en.wikipedia.org/wiki/Foreign_function_interface

uffiとかcffiの説明を端的に言うとlisp処理系でばらばらに定義されている

FFIの書き方の処理系非依存な書き方で書けるような統合を目的とするものでます。


ffiの使い所

Cなら単純なライブラリを使って瞬殺だなーって仕事をlispでやる時に引っ張ってくると良いようです。

過去に使ったことがあったような…

https://github.com/snmsts/cl-libguess/blob/master/guess.lisp

(cffi:load-foreign-library "libguess.so")

(cffi:defcfun ("libguess_determine_encoding" %libguess-determine-encoding) :string
(inbuf :pointer)
(length :int)
(region :string))

単純なffiの利用だとcで書くラッパーとかいらないのでCでdllとかso利用のコード書くのと同程度に簡単です。

逆に嵌り所はgcの無い言語用のライブラリでは資源管理をライブラリがやってくれてたりする場合資源が開放できなくて嵌ったりします。

core吐いたりとかはFFI使うと割と簡単なので経験としてはお勧めです。


uffi/cffiの特徴

uffiは各々の処理系のffi系のインターフェースの統合だけを行なっているのに対し後発のcffiは

文字コードのエンコード変換等々をbabelで行なうなどlispの型とforeign型との変換の為の抽象化を一段持っている感じです。cffiがオススメです。


互換性の範囲

uffi はallegro lispworks cmu openmcl digitool cormanlisp sbcl scl

cffi はopenmcl mcl sbcl cmu scl clisp lispworks ecl allegro cormanlisp abcl

現在割合広く利用されている処理系ではuffiのabcl ecl clispあたりのサポート欠落がcffiを選択したくなる感じでしょうか。cffiがオススメです。


quicklispで各々の利用のされっぷり

どうなってるのかなーと思ったので調べてみました。

(defun list-require (name)

(remove-duplicates
(loop :for system :in
(remove-if-not #'(lambda (system)
(find name (ql-dist:required-systems system) :test #'equal))
(ql:system-list))
:collect (ql-dist:release system))))

(list-require "uffi")

(#<QL-DIST:RELEASE cl-gd-0.6.0 / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-ncurses_0.1.4 / quicklisp 2012-11-25>
#<QL-DIST:RELEASE clsql-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE elephant-20120909-darcs / quicklisp 2012-11-25>
#<QL-DIST:RELEASE html-sugar-20110829-http / quicklisp 2012-11-25>
#<QL-DIST:RELEASE linedit-20120703-git / quicklisp 2012-11-25>)

(list-require "cffi")

(#<QL-DIST:RELEASE antik-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE brlapi-20110619-svn / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cffi-objects-20121013-svn / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cffi_0.10.7.1 / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl+ssl-20121125-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-cairo2-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-charms-20110110-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-devil-20110522-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-fam-20121125-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-fastcgi-20120407-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-fbclient-20121013-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-freetype2-20121013-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-fsnotify-20120520-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-fuse-20121125-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-glfw-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-gpu-20120305-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-gtk2-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-inotify-20120305-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-kyoto-cabinet-20120520-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-libevent2-20121125-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-libxml2-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-m4-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-mw-20120407-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-mysql-20120208-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-openal-20120520-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-opengl-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-plplot-0.6.0 / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-portaudio-20120305-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-proj-20121125-hg / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-rmath-20120703-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-rsvg2-20120107-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-sam-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-skip-list-20101207-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-syslog-20121125-cvs / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-tk-20120407-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-tokyo-cabinet-20111105-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE sqnc-20110110-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE deoxybyte-gzip-20120520-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE deoxybyte-unix-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-ev-20120520-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE ffa-20101006-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE fsbv-20110829-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE glop-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE glu-tessellate-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE gtk-cffi-20121013-cvs / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cells-gtk3-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE hu.dwim.util-20121013-darcs / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-iconv-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE inotify-20120520-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE iolib-0.7.3 / quicklisp 2012-11-25>
#<QL-DIST:RELEASE ip-interfaces-0.1.1 / quicklisp 2012-11-25>
#<QL-DIST:RELEASE lambda-gtk-20120909-cvs / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-async-20121125-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-libusb-20120703-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE lisp-magick-0.71 / quicklisp 2012-11-25>
#<QL-DIST:RELEASE lispbuilder-20120909-svn / quicklisp 2012-11-25>
#<QL-DIST:RELEASE lla-20121013-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-llvm-20121125-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE magicffi-20120703-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE mcclim-20120909-cvs / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-mssql-20120208-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-nxt-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-blapack-20121125-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE fnv-20121125-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE osicat-20120407-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE pal-20111203-cvs / quicklisp 2012-11-25>
#<QL-DIST:RELEASE perfpiece-20120208-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE plain-odbc-20120909-svn / quicklisp 2012-11-25>
#<QL-DIST:RELEASE plokami-20111105-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-png-0.6 / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-proc-20101207-darcs / quicklisp 2012-11-25>
#<QL-DIST:RELEASE pzmq-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE commonqt-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE rcl-20120909-http / quicklisp 2012-11-25>
#<QL-DIST:RELEASE s-protobuf-20110730-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE simple-finalizer-20101006-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-sqlite-20110522-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE static-vectors-1.4 / quicklisp 2012-11-25>
#<QL-DIST:RELEASE teepeedee2-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE thnappy-20110522-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE trivial-features-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE verrazano-20120909-darcs / quicklisp 2012-11-25>
#<QL-DIST:RELEASE mixalot-20120909-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE cl-zmq-20110418-git / quicklisp 2012-11-25>
#<QL-DIST:RELEASE lisp-zmq-1.1.0 / quicklisp 2012-11-25>)

あれ、大分差が…昔思ってたほど今やuffiは使われてない?

cffiがオススメです。


結論

新しくffiを使おうと思った時にはuffiではなくcffiを使いましょうかね…

という結論が初めにありきで書きはじめた感じなんですけど。

体調が悪くて死ねました。

FFIを移植する目的で書くならcffiを使いましょう。

個人としてはuffiを使っているライブラリは使うのを辞めるという方針を取っても良いくらいに思っています。

clsqlのclsql_mysql.cあたりの事を触れようかと思いましたが

恨み節になるのでやめます…