我是第一次使用 .Call。我在下面编写了简单的代码,其中我传递了一个整数并返回一个 SEXP(给 R):
#include <R.h>
#include <Rdefines.h>
SEXP setInt(int *a) {
SEXP myint;
int *p_myint;
int len = 5;
PROTECT(myint = NEW_INTEGER(len)); // Allocating storage space
p_myint = INTEGER_POINTER(myint); // ponit to SEXP object
p_myint[0] = *a;
UNPROTECT(1);
return myint;
}
因此,我调用创建 dll 的 R CMD SHLIB(这里没问题)。
当运行下面的代码(在 R 中)时,我得到的答案不同于c(100,0,0,0,0):
> dyn.load(file.path(path.dll,paste0("useC", .Platform$dynlib.ext)))
> a<-100
> out<- .Call("setInt",as.integer(a))
> out
[1] 536870925 0 0 0 0
PS:可能我得到的是指针变量“a”的地址值,而不是它的值。但我不知道我在这里错过了什么。
编辑:
使用@JoshuaUlrich 的答案,我修复了代码并添加了更多功能。固定代码是:
SEXP setInt(SEXP a,SEXP pos) {
SEXP myint;
int *p_a;
int *p_myint;
int len = 5;
PROTECT(myint = NEW_INTEGER(len)); // Allocate storage space, with default 5 zeroes
p_myint = INTEGER_POINTER(myint); // ponit to SEXP object
p_a = INTEGER_POINTER(a);
p_myint[0] = p_a[(asInteger(pos)-1)]; // get the element at pos
UNPROTECT(1);
return myint;
}
从 R 调用时,您会得到:
a<-c(100,200,300)
pos<-1
out<- .Call("setInt",as.integer(a),as.integer(pos))
> out
[1] 100 0 0 0 0
pos<-2
out<- .Call("setInt",as.integer(a),as.integer(pos))
> out
[1] 200 0 0 0 0