【问题标题】:.C() returns me an empty list.C() 返回一个空列表
【发布时间】:2016-06-22 07:25:21
【问题描述】:

我是 R 的初学者,我正在尝试将用 C 编写的名为 dll.dll.dll 文件加载到 R 中。它似乎有效,现在我想使用以下函数存储在.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"

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

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

subroutine  dll_funk(in9) 
implicit none

!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!***      Declarations: variables, functions
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
integer(4) :: in9
!integer :: in9


! Definitions of variables in the external function calls
!!dec$ attributes c,alias :'dll_funk' :: dll_funk 
!dec$ attributes dllexport            :: dll_funk
!dec$ attributes value                :: in9

open(194,file='outdata.txt')
write(194,*) 'in-value=', in9
! in9 = 1955
close(194)

end subroutine
!end function 

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

另一个问题,你建议我用 .C 运行代码,然后从 C 运行 Fortran 代码,还是只用 Fortran 代码用 .Fortran 运行它更好? 似乎 .Fortran 处理字符串有问题,或者这就是我的理解:Interface func .C and .Fortran

【问题讨论】:

  • 您的通话中可能缺少"。试试dyn.load("2dll.dll")
  • 终于让它工作了,删除了所有的定义并使代码尽可能简单。

标签: c r dll fortran load


【解决方案1】:

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

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

  1. dll_function 必须是 void C 函数,没有返回值。如果这个函数应该返回一些东西,它必须通过修改函数参数来返回;
  2. dll_function 的所有函数参数都必须是指针。

跟进

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

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

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

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

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

是的。这里的另一个答案确实给出了一个玩具示例。你可以看看我半个月前做的this answer。底部有变量类型的总结。

【讨论】:

    【解决方案2】:

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

    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]]
    

    【讨论】:

    • @ZheyuanLi 考虑将其作为编辑添加到您的答案中,但对于编辑来说似乎有点太大了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多