我通过.Call("foo", <args>)调用C代码,其中foo调用其他C函数,计算结果并返回它。 结果是长度为3的列表,我想列出这个列表。 为此,foo做到了这一点:

/* Construct result list from variables containing the results */
SEXP res = PROTECT(allocVector(VECSXP, 3)); /* list of length 3 */
SET_VECTOR_ELT(res, 0, ScalarReal(a)); /* numeric(1) */ 
SET_VECTOR_ELT(res, 1, somenumericvector); /* numeric(<some length>) */
SET_VECTOR_ELT(res, 2, ScalarInteger(i)); /* integer(1) */

/* Name components and return */
SEXP nms = PROTECT(allocVector(STRSXP, 3)); /* names as SEXP */
char *nms_ = CHAR(STRING_ELT(nms, 0)); /* pointer to names */
char *names[3] = {"result_numeric", "result_numeric_vector", "result_integer"};
for(i = 0; i < 3; i++) nms_[i] = names[i]; 
setAttrib(res, R_NamesSymbol, nms);
UNPROTECT(1); 
return res;

这是构建长度为3的命名列表的正确方法吗?

C函数确实返回R但是一旦我将输出分配给R中的变量,我立即得到分段错误。 可能有什么问题? 我可以把'debug statement''(简单的printf("...\\n")放在上面的'return res;'之前,它们被执行得很好。有没有方便的方法来调试从R调用的C代码?

===============>>#1 票数:8 已采纳

到BrodieG的回答另一种方法是使用mkNamed从Rinlinedfuns.h(其中包含如何使用一个例子mkNamed )。

/* Construct named result list from variables containing the results */
const char *names[] = {"result_numeric", "result_numeric_vector",
    "result_integer", ""};                   /* note the null string */
SEXP res = PROTECT(mkNamed(VECSXP, names));  /* list of length 3 */
SET_VECTOR_ELT(res, 0, ScalarReal(a));       /* numeric(1) */ 
SET_VECTOR_ELT(res, 1, somenumericvector);   /* numeric(<some length>) */
SET_VECTOR_ELT(res, 2, ScalarInteger(i));    /* integer(1) */
UNPROTECT(1);
return res;

===============>>#2 票数:5

由于你要求普通的vanilla方式,你需要使用mkCharSET_STRING_ELT从C字符串创建一个R字符向量:

for(i = 0; i < 3; i++) SET_STRING_ELT(nms, i, mkChar(names[i]));  

现在,您正在尝试将原始C字符串用作R对象,这将无法正常工作。

Re:调试,可以在C代码中使用PrintValue打印出R对象。

所有这些都说,除非你有一个非常具体的理由想要普通香草,你应该考虑Rcpp

===============>>#3 票数:1

Per @ nrussell的好建议,单一陈述中的解决方案(为了易读性而分为四行)

R> cppFunction('List marius(double a, NumericVector b, int c) \
       { return List::create(Named("resnum")=a,\ 
                             Named("resvec")=b, \
                             Named("resint")=c); }')
R> marius(1.2, sqrt(3:5), 42L)
$resnum
[1] 1.2

$resvec
[1] 1.73205 2.00000 2.23607

$resint
[1] 42

R> 

  ask by Marius Hofert translate from so

未解决问题?本站智能推荐:

1回复

在C中运行嵌入式R.

我写了一段C代码,声明了一个大小为4x4的方阵。 然后,它从采样的采样函数调用rgig在包GeneralizedHyperbolic在R.它利用从一个GNU GSL库逆矩阵和吐出的结果。 这是从C调用R的练习。 我使用以下代码编译代码: 输出: 当我提交时:
2回复

如何在编写R扩展时返回命名的VECSXP

最近我遇到了一个错误,当我修复它时,我想知道是否有可能返回一个VECSXP(即一个R列表类型),其中元素被命名。 这个c ++代码: 会给我一个R中两个元素(矩阵和向量)的列表: 可以像这样索引: 为了实现这一目标,我需要做些什么改变: 或者这不可能吗?
5回复

将C写为s表达式

我想在s表达式中编写C并使用编译时宏。 有人知道有什么事吗? 它应该将s表达式转换为标准C.
1回复

用C标记s表达式

我正在尝试创建自己的Lisp解释器,并在解析s表达式时遇到了一些问题。 我最初的想法是将表达式标记化并一次处理一个位。 我在尝试失败之后遇到了一些代码来执行此操作 ,但是我对它的输出感到困惑。 用法: 输出: 看一下代码,我曾预料到它会输出17而不是17 '(abc)
2回复

在Emacs中sexp和列表之间的区别?

在Emacs中,有一些命令可以将光标移动到括号(或任何括号)中分隔的表达式中,即forward-sexp,reverse-sexp,forward-list和backward-list。 在Lisp和任何其他代码中它们的行为类似,所以我看到* -sexp和* -list之间没有区别,除了最后一
1回复

在类型上使用'with sexp'会产生“警告4:此模式匹配很脆弱”

我刚开始在自定义类型上使用with sexp语法扩展( 在此处和此处描述)。 但是,我注意到,当我这样做时,我收到有关我的类型的以下警告: Warning 4: this pattern-matching is fragile. It will remain exhaustive when
2回复

使用clojure读/读字符串函数,我如何在.clj文件中读取对象列表

标题是,如果我这样做 这只会给我文件中的第一个对象,这意味着“somefile”如下所示: 然后我只得到(一个obj)作为结果。 我如何得到所有对象的列表,像这样? 谢谢。
2回复

是否有一个C#实用程序用于匹配(语法分析)树中的模式?

我正在开发一个自然语言处理(NLP)项目,在该项目中,我使用语法分析器从给定的句子中创建一个语法分析树。 示例输入:我遇到乔和吉尔,然后我们去购物 示例输出: [TOP [S [S [NP [PRP I]] [VP [VBD运行] [PP [IN进入] [NP [NNP Joe] [C
2回复

Erlang中的递归列表分析

我正在玩Erlang并试图编写一个S表达式解析器。 我发现使用堆栈和循环在Python中这是一个简单的任务,但对于我来说,作为不可变变量和Erlang数据结构的初学者,这是非常重要的。 我需要在Erlang中转换一个列表,如下所示: 到现在为止,我来到这里: 不知道如何获
3回复

在Ruby中寻找关于Sexp表达式的工具[关闭]

我最近很喜欢Ruby中的s-exp表达式。 例如,我发现了Sexpistol解析器。 您是否正在使用其他专用工具(架构等)?