當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。