|
RからGSL(WinXP用) Windows XPでCプログラムからdllを作成するときに、Cプログラム内で GSL(GNU Scientific Library) が提供する関数を使えるようにする。ちなみに、Cygwin は使わず、MinGWとMSYSを使います。
下準備 †MinGW、MSYSおよびActive Perlのインストール †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の修正 †環境変数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ファイルを作成することができません。 GSLのインストール †GSLソースコードの入手 †http://ftp.gnu.org/gnu/gsl/から、最新のもの(2006.9.20現在gsl-1.8.tar.gz)をダウンロードして適当な場所 (例えばc:/temp)などに保存する。 ソースコードの伸張とmake、インストール †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 をすると余計なファイルを消してくれる。
Makevars.winファイルの作成 †作業ディレクトリ(コンパイルしようとする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
めでたしめでたし。 |