我目前正在学习如何在R中调用已编译的C代码。昨天我创建了一个无限π级数的函数,当在R中运行时返回长度为1的数值向量(pi),非常有效。今天我正在编写一个输出变长数值向量的函数,即用户定义的Fibonacci序列。
在《Writing R Extensions》中指出,“编译的代码不应该返回任何东西,除非通过它的参数”。这就是我遇到困难的地方。我不知道如何设置以下C代码的最终“else”语句中的参数,以便在调用“system”后不会触发错误。
我在C程序中编译了一个稍微不同的版本,它可以正常工作。然而,为了符合R函数“.C”的规格,设置方式有所不同。
我该如何更改以下函数,以使其可以编译且没有警告或错误,并且可以在R函数“.C”中调用?
要编译的C代码:
生成了不同的错误。
在《Writing R Extensions》中指出,“编译的代码不应该返回任何东西,除非通过它的参数”。这就是我遇到困难的地方。我不知道如何设置以下C代码的最终“else”语句中的参数,以便在调用“system”后不会触发错误。
我在C程序中编译了一个稍微不同的版本,它可以正常工作。然而,为了符合R函数“.C”的规格,设置方式有所不同。
我该如何更改以下函数,以使其可以编译且没有警告或错误,并且可以在R函数“.C”中调用?
要编译的C代码:
void fibonacci(int *n, int *ans)
{
# *ans = 0; I tried this, didn't work
if(*n == 1 || *n == 2){
*ans = 1;
} else if(*n == 0){
*ans = 0;
} else {
*ans = fibonacci(n - 2) + fibonacci(n - 1); # tried 'ans' in arguments
} # here, didn't work
}
错误发生在这里:
## compile and create shared library
> system('gcc -Wall -g -c -fPIC fibonacciR.c -o fibonacciR.o')
fibonacciR.c: In function ‘fibonacci’:
fibonacciR.c:8:5: error: too few arguments to function ‘fibonacci’
fibonacciR.c:1:6: note: declared here
fibonacciR.c:8:5: error: too few arguments to function ‘fibonacci’
fibonacciR.c:1:6: note: declared here
将C代码中的最终ans
行更改为:
} else {
*ans = fibonacci(n - 2, ans) + fibonacci(n - 1, ans);
}
生成了不同的错误。
> system('gcc -Wall -g -c -fPIC fibonacciR.c -o fibonacciR.o')
fibonacciR.c: In function ‘fibonacci’:
fibonacciR.c:10:5: error: void value not ignored as it ought to be
fibonacciR.c:10:5: error: void value not ignored as it ought to be
我绝对不是一个专业的C程序员,也不知道如何忽略一个参数。此外,这个函数的设置方式,在R中调用它时只会返回一个值。所以我认为我需要为用户定义的参数n循环使用.C。这是正确的吗?
一旦错误得到解决,将要执行的调用如下。
system('gcc -Wall -g fibonacciR.o -shared -o libfibonacciR.so')
## load compiled program into R
dyn.load('libfibonacciR.so')
## create function to call compiled program
fibonacci <- function(n)
{
.C('fibonacci', as.integer(n), ans = as.integer(ans))$ans
}
## call function - result should be first 10 fibonacci numbers
fibonacci(n = 10)
## expected result
[1] 1 1 2 3 5 8 13 21 34 55
c
标签。通过 R 进行编译的设置有所不同。对此感到抱歉。 - Rich Scriven.C
接口,因为它已经过时并且不建议使用。相反,使用.Call()
。另外,也许你不知道有一个内联包?你可能会发现http://adv-r.had.co.nz/C-interface.html很有帮助。 - hadley