RからGSL(WinXP用)
Windows XPでCプログラムからdllを作成するときに、Cプログラム内で GSL(GNU Scientific Library) が提供する関数を使えるようにする。ちなみに、Cygwin は使わず、MinGWとMSYSを使います。
MinGWとMSYSはWindows用バイナリが用意されているので、それを使いましょう。 ダウンロードはhttp://www.mingw.org/download.shtmlから、
MinGWは Priveous -> MinGW -> bin -> MinGW-3.1.0-1.exe, MSYSは Current -> MSYS -> bin -> MSYS-1.0.10.exe,
をダウンロード。ダブルクリックして、デフォルトのままインストールして問題ありませんでした。
Active Perlは、http://www.activestate.com/Products/ActivePerl/Download.htmlから、
Free Download -> Continue
とたどって、適切なバージョン(私の環境ではver. 5.8.8.819, Windows (X86) MSI) をダウンロードし、c:/Perlへインストールます。最後にパスを追加するかどうか聞かれるので、追加しておきましょう。
環境変数PATHの先頭に次の一行
c:/MSYS/1.0/bin;c:/MinGW/bin; (Perlのインストールでパスを追加していない場合は、c:/MSYS/1.0/bin;c:/MinGW/bin;c:/Perl/bin;)
を追加する。必ず先頭に追加してください。R_HOME/binへもパスを通しておきます。これらのパスが正しく設定されていないと、あとで説明するR CMD SHLIBでdllファイルを作成することができません。
http://ftp.gnu.org/gnu/gsl/から、最新のもの(2006.9.20現在gsl-1.8.tar.gz)をダウンロードして適当な場所 (例えばc:/temp)などに保存する。
gsl-1.8.tar.gzをc:/tempに保存したとして、 MSYSを起動し、プロンプト($)で以下のように入力する。
$ cd c:/temp $ tar zxvf gsl-1.8.tar.gz -C /c
c:/にgsl-1.8フォルダができる。MSYSで カレントディレクトリをc:/gsl-1.8に変更し、configureをする。
$ cd c:/gsl-1.8 $ ./configure
自動的に進行するので、しばし待つ。再びプロンプトが現れたら
$ make
をすると、再び自動的に進行するので、これまたしばし待つ(10分以上掛かります)。問題なければ
$ make install
でインストールされる。最後に
$ make clean
をすると余計なファイルを消してくれる。
作業ディレクトリ(コンパイルしようとするxxx.cがあるフォルダ)に、以下の内容を含むMakevars.winファイルをエディタで作成する。
EXTRA_LIBS = -L/usr/local/lib -lgsl -lgslcblas PKG_CPPFLAGS = -I/usr/local/include
これで準備は完了。
mybess.cを、例えばc:/testに作成する。 こんな感じ。
#include <stdio.h> #include <gsl/gsl_sf_bessel.h> void mybessel(double *x, double *y) { *y = gsl_sf_bessel_J0 (*x); }
mybess.cと同じディレクトリにMakevar.winがあることを確認して、DOS窓から次のコマンドを入力。
C:\test>R CMD SHLIB mybess.c
以下のようなメッセージが表示されて、dllファイルが作成される。
making mybess.d from mybess.c gcc -I/usr/local/include -Ic:/R-2.3.1/include -Wall -O2 -c mybess.c -o mybess.o gcc -shared -s -o mybess.dll mybess.def mybess.o -Lc:/R-2.3.1/bin -L/usr/local/lib -lgsl -lgslcblas -lR
なおR Ver. 2.4.0では、最初に"/bin/sh.exe: latex: command not found"というエラーが表示されるものの、無視して差し支えないようです。
RからCへ変数を引き渡すラッパーを作成する。
bess = function(x) { .C("mybessel", as.double(x), result = double(1))$result }
次にRを起動して、動作を確認する。
> setwd("c:/test") > dyn.load("mybess.dll") > bess = function(x) { .C("mybessel", as.double(x), result = double(1))$result } > bess(5) # GSLのベッセル関数による計算結果 [1] -0.1775968 > besselJ(5,0) # Rの組み込み関数による計算結果 [1] -0.1775968
めでたしめでたし。