.C()返回一个空列表

时间:2016-06-22 07:25:22

标签: c r dll fortran load

我是R的初学者,我试图将用C编写的名为.dll的{​​{1}}文件加载到R中。似乎工作,现在我想使用存储在dll.dll文件中的函数,我遇到了问题。

我已在手册中搜索解决方案或其他方法,此处和谷歌。如果我能得到关于使用什么或任何想法的建议,我将非常感激!

我的代码:

.dll

该函数应返回一个数字,1955年。但我似乎无法达到该值。我究竟做错了什么?

使用代码更新(Fortran运行为C),这是dll.dll中的代码:

setwd("C:/Users/MyUser/R")
dyn.load("dll.dll")
is.loaded("DLL_FUNK") 
# For some reason True with capital letters, not in lower case
output <- .C("DLL_FUNK", in9 = as.integer(7))
#output # R Crashes before I can write this.
# R Crashes
# In outdata.txt: "in-value=   139375128"

所以现在当它运行时,R会在写入我的文件(outdata.txt)之前崩溃,但它不是我的号码,也许是某种地址......

另一个问题,您是否建议我使用.C运行代码并从C运行Fortran代码,或者使用.Fortran只运行Fortran代码更好吗? 好像.Fortran处理字符串有问题,或者我理解的是:Interface func .C and .Fortran

2 个答案:

答案 0 :(得分:3)

为什么不将任何参数传递给C函数dll_function?使用.C()时,必须将函数参数作为列表传递。 .C()将返回修改后的列表。所以,如果你什么都没有传递,你什么也得不到。

你的C函数dll_function是什么样的?请注意:

  1. dll_function必须是void C函数,没有返回值。如果此函数应返回某些内容,则必须通过修改函数参数返回;
  2. dll_function的所有函数参数都必须是指针。
  3. <强>后续

      

    dll_function只是测试我是否可以访问它。

    您可以在is.loaded()之后使用dyn.load()来测试您是否有权访问C函数:

    dyn.load("dll.dll")
    is.loaded("dll_function")  ## TRUE
    

    请注意,is.loaded采用C函数名称,而dyn.load()采用.dll名称。通常,您可以在单个.dll文件中使用多个函数。您可以使用is.loaded()检查其中任何一个,以测试是否已成功加载共享库。

      

    所以,如果我想要它返回一些东西,我应该给它一个参数(相同类型?)?

    是。这里的另一个答案确实给出了一个玩具示例。您可以查看我半个月前制作的this answer。在底部有一个变量类型的摘要。

答案 1 :(得分:0)

使用.C时,传递给.C的额外参数将被复制并作为指向被调用c函数的指针传递。然后,此函数可以通过指针修改数据指针。 .C忽略函数的返回值。所以,你的c函数看起来应该是这样的:

void dll_function(int* result) {
  /* Do some complicated computation that results in 1955 */
  (*result) = 1955;
}

你来自R的电话:

.C("dll_function", integer(1))

带输入的示例(这会计算整数向量的总和;此示例假定向量中没有缺失值):

void dll_function2(int* result, int* vector, int* length) {
  int sum = 0;
  for (int i = 0; i < (*length); ++i, ++vector) {
    sum += (*vector)
  }
  (*result) = sum;
}

来自R:

x <- c(1000, 900, 55)
.C("dll_function2", integer(1), as.integer(x), length(x))[[1]]