c - 使用 .Call 获取从 C 到 R 语言的整数 vector

标签 c r

我是第一次使用 .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

P.S: 可能我得到的是指针变量“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

最佳答案

您的 setInt 函数定义接受 C int 作为其唯一参数。但是在您的 R 代码中,您传递的是 INTSXP,而不是 C int。通常,通过 .Call 调用的 C 函数应该只接受 SEXP 作为参数。

因此将您的函数定义更改为:

SEXP setInt(SEXP 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] = AS_INTEGER(a);

   UNPROTECT(1);
   return myint;
}

另请注意,您可能应该确保 aINTSXPlength(a)==1。如果 length(a) > 1,你可以这样做:

int *p_a;
p_a = INTEGER_POINTER(a);
p_myint[0] = p_a[1];  // get second element from a

关于c - 使用 .Call 获取从 C 到 R 语言的整数 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17528551/

相关文章:

c - 为什么这个检查一行是否是回文的程序会返回段错误?

linux - 在 R 中执行 library(package) 报告包是为 i386 构建的,它可以安装在 x86_64 系统上吗?

r - 在不规则网格上绘制气候数据的正确方法

r - 无法在 Linux 中安装 R tseries、quadprog、xts 包

c - fprintf 正在打印两个值而不是一个

c - 使用 strcat(str1,str[pos]) 出现段错误

r - 如何在二维图上绘制 $\alpha$ 置信区域?

R dplyr - 在所有列中都不同

c - 我如何在我的函数下面调用一个函数

c - 在不使用 C 中的第三个变量的情况下交换两个变量的值?