回 帖 发 新 帖 刷新版面

主题:在fortran的动态链接库中怎么引用外部的过程

现有如下代码:
**** modll.f90 ****
      module global
        implicit real(kind(1.d0)) (a-h,o-z)
        !DEC$ ATTRIBUTES DLLEXPORT :: x, n
        allocatable :: x(:)
        integer :: n
      contains
        subroutine tsum(ave)
        !DEC$ ATTRIBUTES DLLEXPORT :: tsum
        real*8 :: ave
        call initial
        write(*,"('dll: the array is: ',/,i4,/,10(5x,5f10.4))") n,(x(i),i=1,n)
        ave = 0
        do i = 1, n
          ave = ave + x(i)
        enddo
        ave = ave / real(n)
        return
        end subroutine tsum
      end module global
----------------------------------------------------------
**** test.f90 ****
      program test
      use global
!
      real*8 ave
      call tsum(ave)
      write(*,"('the average is: ',/,5x,f10.4)") ave
      end
!
      subroutine initial()
      use global
      n = 5
      allocate(x(n))
      do i = 1, n
        x(i) = 10.d0*sin(3.14/real(i))
      enddo
      end subroutine initial
-----------------------------------------------------------
我如何让modll.f90可以编译成dll,并让编译器知道要调用的initial子程序在其它源代码中,并在运行时再链接这个子程序?

回复列表 (共3个回复)

沙发

无法做到。

一个 DLL 在编译时,必须首先给出能调用的所有函数过程:
1.要么这些过程在这个DLL的代码中,这样,这些过程同时被编译成该DLL目标代码。
2.要么这些过程在其他DLL的机器码中,这样,这些其他DLL中的函数过程被目标代码导入。形成DLL依赖

外部函数的调用是编译时的行为,DLL编译以后,只能使用本模块的函数调用或导入其他DLL函数过程。无法再使用代码级的外部函数调用。

解决办法有两个:
1.把 initial 的代码放入DLL
2.把 initial 单独编译成另一个DLL,以便modll使用它。

板凳

或是把initial当成函数指针传进DLL里去。程序总不可能智能到能在整个硬盘自动搜索吧:)

又或者你把initial注册成组件中的接口,那样就可以找到了,但写代码相当麻烦不说,还容易出一些难以控制的问题,在你编程还不熟悉时,先别想得那么复杂:)

3 楼

多谢上面两位老师的解答。看来我只能尝试一下把它做成函数指针链到DLL里去了。

在windows下面真是麻烦呀,同样的程序我在linux下面是完全没有问题的……

我来回复

您尚未登录,请登录后再回复。点此登录或注册