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


R Foreign 对外函数接口


R语言 Foreign 位于 base 包(package)。

说明

调用已加载的编译代码的函数R.

用法

       .C(.NAME, ..., NAOK = FALSE, DUP = TRUE, PACKAGE, ENCODING)
 .Fortran(.NAME, ..., NAOK = FALSE, DUP = TRUE, PACKAGE, ENCODING)

参数

.NAME

给出 C 函数或 Fortran 子例程名称的字符串,或引用此类名称的 "NativeSymbolInfo""RegisteredNativeSymbol""NativeSymbol" 类的对象。

...

要传递给外部函数的参数。最多 65 个。

NAOK

如果 TRUE 则参数中的任何 NANaNInf 值都将传递给外部函数。如果 FALSE ,则 NANaNInf 值的存在被视为错误。

PACKAGE

如果提供,则限制对字符串的搜索.NAME到此参数给出的 DLL(加上常规扩展,‘。所以', '.dll’,……)。

这是为了增加包的安全性,通过使用这个参数可以确保没有其他包可以覆盖它们的外部符号,并且还可以加快搜索速度(请参阅“注意”)。

DUP, ENCODING

为了向后兼容,接受但忽略。

细节

这些函数可用于调用已编译的 C 和 Fortran 代码。后来的接口是.Call.External,更加灵活并且性能更好。

这些函数是 primitive ,并且 .NAME 始终与提供的第一个参数(不应命名)匹配。其他命名参数遵循...,因此不能缩写。为了清楚起见,应避免在传递给 ... 的参数中使用与 .NAME 匹配或部分匹配的名称。

与传入参数的 ... 列表类似的列表(包括为参数指定的任何名称),但反映了 C 或 Fortran 代码所做的任何更改。

参数类型

类型的映射RC 或 Fortran 参数的参数是

R C Fortran
integer int * integer
numeric 双倍的 *双精度
- 或者 - float * real
complex R复合体 *双复合体
logical int * integer
character 字符 **[见下文]
raw 无符号字符 *不允许
list 性经验*不允许
other SEXP不允许

注意:integerlogical 对应的 C 类型是 int ,而不是 S 中的 long 。这种差异在大多数 64 位平台上很重要,其中 int 是 32 位,long 是64 位(但不适用于 64 位 Windows)。

注意:logical 对应的 Fortran 类型是 integer ,而不是 logical :这种差异对某些 Fortran 编译器很重要。

中的数值向量R将作为类型传递double *到 C(并且作为double precisionFortran)除非参数有属性Csingle调成TRUE(使用as.single或者single)。该机制仅用于促进现有 C 和 Fortran 代码的接口。

C型Rcomplex定义于‘Complex.h' 作为一个typedef struct {double r; double i;}。它可能等同于也可能不等同于 C99double complex类型,具体取决于所使用的编译器。

逻辑值以 0 ( FALSE )、1 ( TRUE ) 或 INT_MIN = -2147483648 ( NA ,但仅当 NAOK = TRUE ) 的形式发送,并且编译后的代码应返回这三个值之一:但是 INT_MIN 以外的非零值被映射到 TRUE

缺失的 ( NA ) 字符串值将作为字符串 "NA" 传递给 .C。由于 C char 类型可以表示所有可能的位模式,因此似乎无法区分丢失的字符串和字符串 "NA" 。如果这种区别很重要,请使用 .Call

不推荐使用带有 .Fortran 的字符串,并且会发出警告。它将字符向量的第一个(唯一)字符串作为 C 字符数组传递给 Fortran:如果单独传递其真实长度,则可以将其用作 character*255。最多仅传回字符串的 255 个字符。 (它的工作效果如何,甚至是否有效,都取决于 C 和 Fortran 编译器以及平台。)

列表、函数或其他R对象可以(由于历史原因)传递给.C,但是.Call接口是更优选的。除了原子向量之外的所有输入都应被视为只读,并且除了向量(包括列表)之外的所有输入、函数和环境现在均已弃用。

Fortran 符号名称

所有已知可用于编译的 Fortran 编译器R将符号名称映射为小写,也是如此.Fortran.

包含下划线的符号名称在 Fortran 77 中无效(尽管它们在 Fortran 9x 中有效)。许多 Fortran 77 编译器将允许它们,但可能会以不同的方式将它们转换为不包含下划线的名称。此类名称通常会与.Fortran(因为它们的翻译方式是在R被构建并使用的信息.Fortran),但可移植代码不应使用包含下划线的 Fortran 名称。

采用.Fortran小心编译的 Fortran 9x 代码:如果使用的 Fortran 9x 编译器与配置时使用的 Fortran 编译器不同,则可能无法工作R,特别是当子例程名称不是小写或包含下划线时。调用 Fortran 9x 代码的最便携方式R是使用.C和 Fortran 2003 模块iso_c_binding为 Fortran 代码提供 C 接口。

复制参数

在调用编译代码并收集结果之前复制字符向量。对于其他原子向量,如果在调用代码中以其他方式使用参数,则在调用编译代码之前复制参数。

非原子向量对象对于 C 代码来说是只读的,并且永远不会被复制。

可以通过设置 options(CBoundsCheck = TRUE) 来更改此行为。在这种情况下,原始、逻辑、整数、双精度和复数向量参数在调用编译代码之前和之后都会被复制。制作的第一个副本在每一端都通过保护字节进行扩展,并且在返回时检查这些字节是否未被更改。对于 .C ,字符向量的每个元素都使用保护字节。

注意

如果要频繁使用这些函数之一,请指定 PACKAGE(将搜索限制为单个 DLL)或将 .NAME 作为本机符号对象之一传递。搜索符号可能需要很长时间,尤其是在加载许多命名空间时。

你可能会看到PACKAGE = "base"对于链接到的符号R。不要在您自己的代码中使用此符号:此类符号不是 API 的一部分,可能会在没有警告的情况下进行更改。

参考

Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New S Language. Wadsworth & Brooks/Cole.

也可以看看

dyn.load.Call

“编写 R 扩展”手册。

相关用法


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