下面是一个在R中创建3个矩阵的最小例子,应该通过调用C代码进行操作。
简而言之,我想将矩阵A从R传递给C,然后将一些值复制到W和H矩阵。后者2我希望在R中返回修改后的值。
但是,这不太有效(段错误,或返回空矩阵)。我怀疑R复制对象以供在C中使用,而不是通过引用传递它们。
C source(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))
现在我的问题:
而且,最重要的是,
答案 0 :(得分:1)
这可能是因为你的函数采用整数,而.C
接口会传入指针。你的签名应该是
void test(double *A, double *W, double *H, int *m, int *n, int *k)
在您对DUP=FALSE
的通话中设置.C
会阻止.C
复制您传入其中的阵列。有关详细信息,请参阅?.C
。
C函数不返回任何内容,但R函数.C
返回一个列表,对应传递给C函数的参数。再次,请参阅?.C
。
你有两个选择。第一种是设置DUP=FALSE
并让C函数修改现有的R对象。但是,如果执行此操作,则需要确保在将as.double
传递给外部调用之前调用as.double
,否则W
将被强制创建新对象,因为当前定义{{1} }和H
将是整数类型。
您的第二选择是离开DUP=TRUE
,并使用.C
来电中的返回值,如下所示:
result<-.C("test", as.double(A), W=as.double(W), H=as.double(H),
as.integer(m), as.integer(n), as.integer(k))
W<-result$W
H<-result$H