本文介绍了在R中使用Fortran子例程?未定义的符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 这是对我以前的问题进行跟踪的 一>。我将Fortran代码包装在一个模块中,现在它在我运行时编译: R CMD SHLIB ./Fortran/Fpi.f90 这是我的Fortran代码: 包含子程序pi(avepi,DARTS,ROUNDS)双精度,意图(out):: avepi 整数,意图(in):: DARTS,ROUNDS 整数:: MASTER,rank,i,n 整数,allocatable :: seed(:) 双精度:: pi_est ,homepi,pirecv,pisum,dboard !我们在连续运行中将其设置为零等级= 0 !初始化随机数发生器!我们确保每个任务的种子不同调用random_seed()调用random_seed(size = n) allocate(seed(n)) seed = 12 + rank * 11 调用random_seed(put = seed(1:n))解除分配(种子) avepi = 0 do i = 0,ROUNDS-1 pi_est = dboard(DARTS)!计算pi在所有迭代中的平均值 avepi =((avepi * i)+ pi_est)/(i + 1) end do 结束子程序pi 双精度函数dboard(飞镖)整数,意图(in)::飞镖双精度:: x_coord,y_coord 整数::得分,n 分数= 0 做n = 1,飞镖呼叫随机号码(x_coord)呼叫随机号码(y_coord) if((x_coord ** 2 + y_coord ** 2)得分=得分+ 1 结束如果结束做 dboard = 4.0d0 *得分/飞镖 结束函数 结束模块Fpi 我试图在R中运行它: mypi dyn .load(./ Fortran / Fpi.so) retvals< - .Fortran(pi,DARTS = as.integer(DARTS),ROUNDS = as.integer(ROUNDS),avepi = as。数字(1)) return(retvals $ avepi)} mypi(DARTS = 50000,ROUNDS = 10) 和我得到这个错误: dyn.load错误(./ Fortran /Fpi.so):无法加载共享对象'/home/ignacio/local/projects/PI/./Fortran/Fpi.so': / home / ignacio / local / projects / PI /./ Fortran / Fpi.so:undefined symbol:dboard_ 解决方案您的问题归结为 dboard 的声明: double precision :: pi_est,homepi,pirecv,pisum,dboard 在这里您要说 dboard 是一个外部函数,而不是一个模块过程。这解释了为什么有符号 dboard _ 进场。你想删除它: 双精度:: pi_est,homepi,pirecv,pisum ,而是依赖于 pi 对 dboard : pi 在没有此声明的情况下已经知道它。 除此之外,因为 pi 在模块中,这个子例程本身会出现一些名称混乱。我可以通过将 pi 本身作为(C)可互操作的过程来解决这个问题。 $子程序pi(avepi,DARTS,ROUNDS)bind(C) use,intrinsic :: iso_c_binding,only:c_double,c_int real(c_double),intent(out):: avepi 整数(c_int),intent(in):: DARTS,ROUNDS ... ,然后使用 .C 而不是 .Fortran 。 您可以保留 pi 和 dboard ,而后者甚至不需要互操作。 This is a follow up to my previous question. I wrapped my Fortran code in a module and now it compiles when I run:R CMD SHLIB ./Fortran/Fpi.f90This is my Fortran code:Module Fpi IMPLICIT NONEcontains subroutine pi(avepi, DARTS, ROUNDS) double precision, intent(out) :: avepi integer, intent(in) :: DARTS, ROUNDS integer :: MASTER, rank, i, n integer, allocatable :: seed(:) double precision :: pi_est, homepi, pirecv, pisum, dboard ! we set it to zero in the sequential run rank = 0 ! initialize the random number generator ! we make sure the seed is different for each task call random_seed() call random_seed(size = n) allocate(seed(n)) seed = 12 + rank*11 call random_seed(put=seed(1:n)) deallocate(seed) avepi = 0 do i = 0, ROUNDS-1 pi_est = dboard(DARTS) ! calculate the average value of pi over all iterations avepi = ((avepi*i) + pi_est)/(i + 1) end do end subroutine pi double precision function dboard(darts) integer, intent(in) :: darts double precision :: x_coord, y_coord integer :: score, n score = 0 do n = 1, darts call random_number(x_coord) call random_number(y_coord) if ((x_coord**2 + y_coord**2) <= 1.0d0) then score = score + 1 end if end do dboard = 4.0d0*score/darts end functionend module Fpi I'm trying to run this in R:mypi <- function(DARTS, ROUNDS) { dyn.load("./Fortran/Fpi.so") retvals <- .Fortran("pi", DARTS = as.integer(DARTS) , ROUNDS = as.integer(ROUNDS), avepi = as.numeric(1)) return(retvals$avepi)}mypi(DARTS = 50000, ROUNDS = 10)and I get this error:Error in dyn.load("./Fortran/Fpi.so") : unable to load shared object '/home/ignacio/local/projects/PI/./Fortran/Fpi.so': /home/ignacio/local/projects/PI/./Fortran/Fpi.so: undefined symbol: dboard_ 解决方案 Your problem comes down to the declaration of dboard: double precision :: pi_est, homepi, pirecv, pisum, dboardHere you are saying that dboard is an external function, rather than a module procedure. This explains why there is a symbol dboard_ coming into play. You want to remove that:double precision :: pi_est, homepi, pirecv, pisumand instead rely, in pi on the module procedure-ness of dboard: pi already knows about it without this declaration.Now, beyond that, because pi is in a module there is going to be some name mangling going on for that subroutine itself. I'd solve this problem by making pi itself a (C) interoperable procedure.Module Fpi IMPLICIT NONEcontains subroutine pi(avepi, DARTS, ROUNDS) bind(C) use, intrinsic :: iso_c_binding, only : c_double, c_int real(c_double), intent(out) :: avepi integer(c_int), intent(in) :: DARTS, ROUNDS ...and then using .C rather than .Fortran.You can keep pi and dboard in the module, and this latter needn't even be interoperable. 这篇关于在R中使用Fortran子例程?未定义的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 09-18 03:59