以下は、C コードを呼び出して操作する必要がある R で 3 つの行列を作成する最小限の例です。
要するに、行列 A を R から C に渡し、いくつかの値を W 行列と H 行列にコピーしたいと考えています。後者の2つは、変更された値でRに戻したいです。
ただし、これはうまくいきません ( segfault、または空の行列が返されます)。R はオブジェクトを参照渡しするのではなく、C で使用するためにコピーしていると思われます。
C ソース (test.c):
void test(double *A, double *W, double *H, int m, int n, int k) {
// A is input with dimensions (m,n)
// W has dimensions (m,k)
// H has dimensions (k,n)
int i;
for(i=0; i<m*k; i++)
W[i] = A[i];
for(i=0; i<k*n; i++)
H[i] = A[i];
}
いくつかのビルド手順 (Makefile):
CCFLAGS = -fPIC
all: shared
shared: test.o
$(CC) -shared -Wl,-soname,test.so -o test.so test.o
test.o: test.c
$(CC) $(CCFLAGS) -c $<
それを呼び出す R コードは次のとおりです。
dyn.load("test.so")
m = 3
n = 3
k = 2
A = matrix(c(1:(m*n)), nrow=m, ncol=n)
W = matrix(0, nrow=m, ncol=k)
H = matrix(0, nrow=k, ncol=n)
.C("test", as.double(A), as.double(W), as.double(H),
as.integer(m), as.integer(n), as.integer(k))
今私の質問:
- ほとんどの場合、このセグメンテーション違反が発生するのはなぜですか?
- 初期化されていない R 行列で C 関数を呼び出す方法はありますか?
- 「void」関数が何かを返すのはなぜですか?
最も重要な、
- これを機能させる方法は?