从R矩阵读取/写入C数组

时间:2013-10-25 22:43:30

标签: c r wrapper

下面是一个在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))

现在我的问题:

  • 为什么大部分时间都会出现这种错误?
  • 有没有办法用未初始化的R矩阵调用C函数?
  • 为什么'void'函数会返回什么内容?

而且,最重要的是,

  • 如何让这个工作?

1 个答案:

答案 0 :(得分:1)

  • 为什么大部分时间都会出现这种错误?

这可能是因为你的函数采用整数,而.C接口会传入指针。你的签名应该是

void test(double *A, double *W, double *H, int *m, int *n, int *k)
  • 有没有办法用未初始化的R矩阵调用C函数?

在您对DUP=FALSE的通话中设置.C会阻止.C复制您传入其中的阵列。有关详细信息,请参阅?.C

  • 为什么'void'函数会返回什么内容?

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