当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


R package_native_routine_registration_skeleton 编写用于将本机例程注册添加到包的框架


R语言 package_native_routine_registration_skeleton 位于 tools 包(package)。

说明

编写一个框架,用于将本机例程注册添加到包中。

用法

package_native_routine_registration_skeleton(dir, con = stdout(),
    align = TRUE, character_only = TRUE, include_declarations = TRUE)

参数

dir

包的顶级目录。

con

要写入骨架的连接:可以指定为文件路径。

align

逻辑:登记表应该每列排成三列吗?

character_only

逻辑:应该只.NAME由字符串指定的参数(而不是作为名称)R对象或表达式)被提取?

include_declarations

逻辑:输出是否应该包含已注册例程的声明(也称为‘prototypes’)?

细节

注册在“编写 R 扩展”的“注册本机例程”部分中进行了说明。该函数生成 C 代码的骨架,需要添加该骨架才能启用注册,通常为文件‘src/init.c’或附加到包的唯一 C 文件中。

该函数检查‘R' 调用包的目录.C,.Fortran,.Call.External并为其能够理解的人创建注册信息。如果无法确定所使用的参数数量,它将被记录为-1:这样的值应该被纠正。

可选地,框架将包括注册例程的声明:应根据 C/Fortran 源代码检查它们,尤其是参数数量取自R代码。为了.Call.External调用他们通常就足够了,但是对于.C.Fortran称为‘⁠无效*⁠' 参数最好由实际类型替换。否则,需要包含声明(如果附加到文件,它们可能存在于该文件的较早位置,或者存在于可包含在‘init.c’)。

character_only 的默认值适用于处理没有任何现有注册的包:character_only = FALSE 可用于建议对自注册以来已扩展的包进行更新。对于默认值,如果发现 .NAME 值不是字符串(例如名称或表达式),则会通过输出中的注释进行注释。

使用早期创建形式的包R原生符号对象通过中的附加参数useDynLib指令可能最容易更新为使用注册character_only = FALSE.

如果入口点与包中不同数量的参数一起使用R代码,为每个数字在表中创建一个条目(以及可选的声明),并在输出中放置注释。需要解决的问题是:仅.External调用可以具有可变数量的参数,应将其声明为-1.

数量惊人CRAN包有调用R代码未包含在包中的本机例程中,这将导致在添加注册 C 代码时在包安装过程中出现“加载失败”错误。

未命名例程(例如.Call(...))的调用将被静默忽略。

无:输出写入连接 con

提取 C/C++ 原型

有多种工具可用于从 C 或 C++ 代码中提取函数声明。

例如,对于 C 代码,可以使用cproto(https://invisible-island.net/cproto/cproto.html;Windows 可执行文件可用)

    cproto -I/path/to/R/include -e *.c
  

ctags(通常随操作系统分发)涵盖 C 和 C++。,使用类似

    ctags -x *.c
  

列出所有函数的用法。 (“Exuberant”版本允许更多控制。)

提取 Fortran 原型

gfortran 9.2 及更高版本可以使用特殊标志提取 Fortran 子例程的 C 原型:

    gfortran -c -fc-prototypes-external file.f
  

尽管具有讽刺意味的是,不适用于声明 bind(C) 的函数。

注意

这仅检查‘R’目录:它不会找到例如.Call直接在示例、测试中使用的调用ETC.

静态代码分析用于查找.C等调用:它将要找到那些在部分R通过包含在中“注释掉”代码if(FALSE) { ... }。另一方面,它将无法找到像这样的结构中的入口点

    .Call(if(int) "rle_i" else "rle_d", i, force)
  

并且不知道调用中变量的值,例如

    .Call (cfunction, ...)
    .Call(..., PACKAGE="sparseLTSEigen")
  

(但如果 character_only 为 false,则将第一个提取为 "cfunction" )。尚未完全解决的调用将通过输出文件中的注释进行注释。

如果其他包中的入口点具有显式(字符串)PACKAGE 参数,则对它们的调用将被忽略。

例子

## Not run: 
## with a completed splines/DESCRIPTION file,
tools::package_native_routine_registration_skeleton('splines',,,FALSE)
## produces
#include <R.h>
#include <Rinternals.h>
#include <stdlib.h> // for NULL
#include <R_ext/Rdynload.h>

/* FIXME: 
   Check these declarations against the C/Fortran source code.
*/

/* .Call calls */
extern SEXP spline_basis(SEXP, SEXP, SEXP, SEXP);
extern SEXP spline_value(SEXP, SEXP, SEXP, SEXP, SEXP);

static const R_CallMethodDef CallEntries[] = {
    {"spline_basis", (DL_FUNC) &spline_basis, 4},
    {"spline_value", (DL_FUNC) &spline_value, 5},
    {NULL, NULL, 0}
};

void R_init_splines(DllInfo *dll)
{
    R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
    R_useDynamicSymbols(dll, FALSE);
}

## End(Not run)

也可以看看

package.skeleton

相关用法


注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 Write Skeleton for Adding Native Routine Registration to a Package。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。