cygwinでWidonwsのRとCの連携 64bit版 。 RからC言語の関数を呼ぶ

  • まず、Rには、C言語との連携に .C関数と.Call 関数が用意されている。

.C関数は簡便用で、.Call関数は、C言語からRのオブジェクトを操作できる。

ここでは、.C関数を利用する。

以下のサイトを参考にしました。

http://www.okada.jp.org/RWiki/?R%A4%AB%A4%E9%C2%BE%B8%C0%B8%EC%CD%F8%CD%D1
http://d.hatena.ne.jp/rindai87/20100102/1262443332

http://d.hatena.ne.jp/syou6162/20090117/1232120983
http://cran.r-project.org/doc/contrib/manuals-jp/R-exts.jp.pdf

64bitにコンパイルできてるかの判定は以下を参考にした。
http://sow23.blog.fc2.com/blog-entry-14.html
sizeof(*void)が8になる。32bitだと4

64bitでの最大のポイントは、
64bit版の x86_64-w64-mingw32-gcc を利用する。

  • 具体的には、

(1)cygwin をインストール
(2)cygwinのsetup.exeから、x86_64-w64-mingw32-gccをインストール
(3)たとえば、以下の関数を作る
mysum.c

void mysum(double *a, double *b, double *c){


        double sum;
        sum= *a + *b;
        *c=sum;
}

(4)コンパイル cygwin ターミナル上で
コンパイルとダイナミックライブラリ dll化

x86_64-w64-mingw32-gcc mysum.c -c
x86_64-w64-mingw32-gcc -shared mysum.o -o mysum64c.dll


(5)WindowsのRから呼び出す。

dyn.load("myfun64c.dll")

(6)以下の関数をつくる

mysum<-function(a,b){

.C("mysum",arg1=as.double(a),arg2=as.double(b),arg3=double(1))

}

(7)実行

z<-mysum(1.234,2.345)

(8)結果

z
$arg1
[1] 1.234

$arg2
[1] 2.345

$arg3
[1] 3.579
  • もう少し複雑な例(ベクトル返し)

Cのコード

void mysum5(double *a,double *b,double *c,int *n){
        int i;
        for(i=0;i<*n;i++){
                c[i]=a[i]+b[i];
        }

}


Rのコード

dyn.load("mysum5.dll")

mysum5<-function(a,b){

	.C("mysum5",arg1=as.double(a),arg2=as.double(b),arg3=as.double(c(1,1,1)),arg4=as.integer(length(a)))$arg3
}

実行結果

mysum5(a=c(1,2,3),b=c(3,3,4))
[1]4 5 7