English / Japanese
c-wrapper - A Generic Wrapper for C Libraries
最終更新日: 2009年8月9日
c-wrapperとは
c-wrapperとはCやObjective-Cで書かれたライブラリを呼び出すためのFFI(Foregin Function Interface)です。
c-wrapperはヘッダファイルをパーズする機能を持っているため、関数、グローバル変数、定数に関する定義を行う必要がありません。
サンプルコード
c-wrapperを用いると以下のようなコードを書くことができます。
(use c-wrapper)
(c-load "stdio.h")
(printf "Hello, world\n")
MacOSXではObjective-Cのライブラリを呼び出すことも可能です。
(use objc-wrapper)
(c-load "Cocoa/Cocoa.h"
:libs "-framework Foundation -framework Cocoa")
[[NSAutoreleasePool :alloc] :init]
(define s [[NSSpeechSynthesizer :alloc] :init])
[s :startSpeakingString (@ "Hello, world")]
(do () ((eq? [s :isSpeaking] NO)))
必要な環境
c-wrapperを動作させるためにはGauche 0.8.14以降の環境とGCCが必要です。なお、動作確認は以下の環境で行いました。
- MacOSX 10.5.8 x86
- Linux 2.6.28-14 x86 (ubuntu 9.04)
- Linux 2.6.28-14 x86_64 (ubuntu 9.04)
- FreeBSD 7.1 x86
- FreeBSD 7.1 x86_64
- NetBSD 4.0.1 x86
- NetBSD 4.0.1 x86_64
- Windows XP SP3 (Cygwin 1.5.25)
ダウンロード
インストール方法
インストールにはgauche-packageを利用する手順と、展開した後自分でconfigure & makeを行う手順があります。
gauche-packageを利用する場合
以下のコマンドを入力します。
% gauche-package install c-wrapper-0.6.0.tgz
自分でconfigure & makeを行う場合
以下のコマンドを入力します。なお、make
にはGNU makeを使用してください。
% tar zxvf c-wrapper-0.6.1.tgz
% cd c-wrapper-0.6.1
% ./configure
% make
% make install
cwcompileの使い方
cwcompileはヘッダファイルをパーズし共有ライブラリを作成するツールです。ランタイム時のヘッダファイルのパーズがなくなるため、起動時間が短縮できます。使い方は以下の通りです。
まず、ふつうにc-wrapperを使ったコードを作成します。
(define-module mymodule
(use c-wrapper)
(c-load '("stdio.h" "wand/magick_wand.h")
:cppflags-cmd "Wand-config --cppflags"
:ldflags-cmd "Wand-config --ldflags"
:libs-cmd "Wand-config --libs"
:compiled-lib "magicklib")
(export-all))
...
(provide "mymodule")
このコードが動くことを確認した後、以下のコマンドを実行します。
% cwcompile mymodule.scm
ここで作成された magicklib.so をパス上に置いておくと、先のmymodule.scmをロードしたときに、ヘッダファイルをパーズするのではなく、この共有ライブラリがロードされるようになります。
cwcompileを使ったサンプルのムービーもあるので、参考にしてください。
制限事項
_Bool
はint
型として扱われます。
long double
は使用できません。プロトタイプ宣言に存在してもエラーとはなりませんが、関数呼び出しで値を渡すことができません。
- 構造体のアラインメントを変更している場合には対応できません。
- Objective-C 2.0 の@propertyは無視されます。
更新履歴
- 2009-8-9: バージョン0.6.1リリース
-
- 関数をリネームするようなマクロ定義がうまく動作しないバグを修正しました。
- ビットフィールドを含む構造体のオフセット計算が間違っていたのを修正しました。
- Cygwin版Gaucheに対応しました。
- 2009-6-27: バージョン0.6.0リリース
-
- Cパーサのスピードが向上しました。
- Cの関数呼び出し時のオーバヘッドが低減しました。
- '#define FOO foo()'のようなマクロも扱えるようになりました。
- c-loadに:hide-symbolsオプションが追加されました。
- 2009-2-21: バージョン0.5.6リリース
-
- NetBSD x86_64に対応しました。
- __attribute__((__mode__(x)))に対応しました。
- configureオプションに--with-rpathを追加しました。
- 2009-2-14: バージョン0.5.5リリース
-
- Linux x86_64, FreeBSD x86_64に対応しました。
- NX保護機能が動作している場合でも、クロージャから生成した関数ポインタを呼び出せるようにしました。
- <c-ptr>のrefに対するsetterを定義しました。
- configure実行時にldconfigを探索する箇所で、PATHで見つからなければ/sbin, /usr/sbinも探すように修正しました。
- 2008-5-11: バージョン0.5.4リリース
-
- Objective-C 2.0のコードをパースできるようにしました。
- ptr->string, x->stringでポインタから<string>オブジェクトを生成するときに、元の文字列をコピーするようにしました。
- 2007-5-21: バージョン0.5.2リリース
-
- Linux環境において /usr/include/sys/types.h で定義されている int*_t, u_int*_t の型が正しく定義できなかった問題に対し、暫定的な対応を行いました。
- GCC拡張の Unnamed struct/union fields within structs/unions の対応を行いました。
- <c-func-ptr>に対するderefの定義を追加しました。
- C99の配列要素中の記憶/型修飾子に対応しました。
- 2007-1-6: バージョン0.5.1リリース
-
- 関数ポインタに対してobject-applyを定義しました。これにより関数ポインタを通常の手続きのように扱うことができます。
- c-load, c-includeで:importを使用したときにエラーが発生することがあるというバグを修正しました。
- c-load-library, c-ldで'-Wl'オプションが使用できるようになりました。
- <foreign-pointer>を<c-ptr>にキャストできるようになりました。
- Cで"foo->bar"に相当する処理を"(ref foo 'bar)"と書けるようになりました。
- 2006-12-26: バージョン0.5.0リリース
-
- 共有ライブラリを作成するためのcwcompileコマンドが追加されました。これに伴い、今までのgenwrapperコマンドは廃止されました。
- 新しいマクロc-loadが追加されました。c-loadはc-load-libraryとc-includeを一度に行うためのマクロです。
- c-load, c-includeで選択したオブジェクトのみ定義することができるようになりました。
- make-c-arrayの名前がc-arrayに変更になりました。古い名前でも使用できますが、後のバージョンでは削除されます。
- Objective-Cのクラスとメソッドを定義するためのdefine-objc-classとdefine-objc-methodが追加されました。
- 関数ポインタ周りの扱いにバグがあったのを修正しました。(Reported by HIBINO Kei)
- 2006-08-25: バージョン0.4.4リリース
-
- インライン関数を参照しているマクロが登録されないというバグを修正しました。
- 2006-08-20: バージョン0.4.3リリース
-
- マクロ登録のアルゴリズムを修正し、マクロ本体で別のマクロを使用している場合や、本体が文(statement)の場合にも対応しました。
- 2006-08-06: バージョン0.4.2リリース
-
- インライン関数に対応しました。インライン関数のソースコードからSchemeのコードを生成するようになっています。ただしswitchやgotoなどラベルを使用するものはサポートしていません。
- 2006-07-24: バージョン0.4.1リリース
-
- (c-struct tagname), (c-union tagname)というマクロを追加しました。構造体や共用体をタグ名で参照する場合は、<c-struct:...>や<c-union:...>といったシンボルを直接参照するのではなく、これらのマクロを使うようにしてください。
- マクロ登録のアルゴリズムを修正しました。以前のバージョンではc-includeで登録できない関数形式のマクロがいくつかありました(例えばX11/Xlib.hのWhitePixel)が、今回のバージョンからこういったマクロも使用できるようになりました
- 識別子がないときの関数ポインタ宣言(例えば、void (*)((void*)foo))が正しくパーズできなかったのを修正しました
- 2006-06-11: バージョン0.4.0リリース
-
- Intel Macに対応しました
- Objective-Cに対応しました(MacOSXのみ)
- FreeBSDで関数の戻り値が構造体・共用体であっても正しく動作するようになりました
- ポインタオブジェクトに対してファイナライザを指定できるようになりました。ただしポインタが使用中かそうでないかを完璧に判定することができないので、使うときには注意が必要です。
- infoドキュメントを追加しました(内容はまだ不完全です)
- 2006-04-30: バージョン0.3.4リリース
-
- 可変長引数の関数を複数回呼び出したときに正しく引数が渡されないことがあるというバグを修正しました
- 2006-04-15: バージョン0.3.3リリース
-
- Universal character namesのバグを修正しました
- 2006-04-02: バージョン0.3.2リリース
-
- null-ptr?が正しく動作しないバグを修正しました。
- 関数形式のマクロはprocedureでなくマクロとして定義するように修正しました。
- 2006-03-25: バージョン0.3.1リリース
-
- 構造体のビットフィールドを扱えるようにしました。
- 共有ライブラリのロードパスに環境変数(LD_LIBRARY_PATH, DYLD_LIBRARY_PATH)の内容を反映させるようにしました。
- 2006-03-19: バージョン0.3.0リリース
-
- c-load-libraryで.la形式のファイルを扱えるようにしました。
- 関数形式のマクロ(functionlike macro)もパーズできるようにしました。
- libffiをGCC 4.1.0のものに置き換えました。
- 2006-03-12: バージョン0.2.0リリース
-
- パーズ済みのコードを生成するgenwrapperコマンドを追加しました。
- c-load-libraryの機能を追加しました。
- タグ名を使用した構造体・共用体の参照の仕方を変更しました。これに伴い、c-struct, c-unionが廃止されています。
- NULLポインタの取り扱いをまともにしました。関数ポインタに対しNULLポインタを渡せるようになりました。
- 2006-03-04: バージョン0.1リリース
-