首页 > 解决方案 > R 如何在动态库中提取函数定义

问题描述

当有定义在source.clike中的函数时

#include <R.h>
#include <Rdefines.h>

SEXP myfunc (SEXP n1, SEXP n2){
    SEXP mysum_sexp;
    PROTECT(mysum_sexp = NEW_NUMERIC(1));
    PROTECT(n1);
    PROTECT(n2);
    NUMERIC_POINTER(mysum_sexp)[0] = NUMERIC_POINTER(n1)[0] 
                                   + NUMERIC_POINTER(n2)[0];
    UNPROTECT(3);
    return(mysum_sexp);
}

并且该source.c文件是使用编译的

R CMD SHLIB source.c

使用默认名称创建动态(共享)库source.so。编译过程结束后,当我们输入R

> dyn.load("source.so")

编译代码中的函数可以使用 as 调用

> .Call("myfunc", 4, 7)

结果11和预期的一样。如何R在不知道函数定义的情况下将参数传递给外部函数?调用过程是空白的还是R遵循带有 n 个参数类型为SEXPfor的标准定义n = 1, 2, ..., n1

我知道不使用.Call接口Rcpp是老式的,但我想了解它背后的机制。

提前致谢。

标签: cr

解决方案


感谢MrFlick,他给我发了dotcode.c的源链接,这段代码解释了我的问题:

switch (nargs) {
case 0:
  retval = (SEXP)ofun();
  break;
case 1:
  retval = (SEXP)fun(cargs[0]);
  break;
case 2:
  retval = (SEXP)fun(cargs[0], cargs[1]);
  break;
case 3:
  retval = (SEXP)fun(cargs[0], cargs[1], cargs[2]);
  break;
case 4:
  retval = (SEXP)fun(cargs[0], cargs[1], cargs[2], cargs[3]);
  break;
case 5:
  .
  .
  .
case 65:
.
.
default:
}

它似乎R着眼于参数的数量并遵循一个标准定义,该定义在运行时需要几个(或没有)SEXP 参数。允许的最大参数数是65。众所周知,所有函数都返回一个 SEXP。情况是手工编码的。这证明了外部函数调用是空白的,也就是说,输入参数的数量直接决定了函数的定义。


推荐阅读