Fortran Coder

标题: 关于Fortran在IVF编译器下DLL文件生成和调用的问题 [打印本页]

作者: 一个憎学家    时间: 2024-5-21 15:57
标题: 关于Fortran在IVF编译器下DLL文件生成和调用的问题
帖主目前使用的编译器是Intel(R) Visual Fortran Intel(64位),现在想通过该编译器在命令行下对源文件subtest.f90进行编译并生成动态库文件,再在另一个主程序main.f90中调用该动态库文件中的函数。
subtest.f90中的内容非常简单,只包含一个subroutine,其功能是输入圆的半径R,计算其面积S,以下该源文件的代码:
[Fortran] 纯文本查看 复制代码
subroutine SUB(S,R)
!程序作用是根据传入的圆的半径R,计算圆的面积S
!DEC$ ATTRIBUTES DLLEXPORT :: SUB
!上面的语句是编译功能语句,DLL中可以被外界调用的函数都要写上面的语句,声明哪些函数可以被外界访问,不然外界无法访问。
implicit none
double precision S,R
write(*,*)"You are using subroutline in DLL"
S=3.141592653*R**2!计算的面积可以通过传址传出去
return
end

编写完subtest.f90后,我在命令行下通过IVF编译器,输入指令:ifort /dll /fPIC /o subtest.dll subtest.f90,成功生成了三个同名的.dll,.lib和.exp文件。
主程序main.f90也非常简单,只起到调用该动态库中的SUB(S,R)子程序并显示计算结果的作用,以下是相关代码:
[Fortran] 纯文本查看 复制代码
program main
    !!DEC$OBJCOMMENT LIB:'Dll1.lib'
!    !DEC$OBJCOMMENT LIB:'dllcmd.lib'
    !DEC$OBJCOMMENT LIB:'subtest.lib'
    implicit none
    interface
    subroutine SUB(S,R)
    !DEC$ ATTRIBUTES DLLEXPORT :: SUB
    real*8 s,r
    end subroutine
    end interface
    real*8 rad,area
    rad=10.0
    call SUB(area,rad)
    write(*,*)'计算结果为:',area
end program





作者: 一个憎学家    时间: 2024-5-21 16:01
接上文(有发帖字数限制):
我在vs2013下基于上述主程序成功调用了动态库文件(在C语言的主程序下也成功调用,C中采用的隐式调用,只调用了dll)
但是我在cmd下想通过ivf编译器,利用subtest.dll和main.f90共同编译生成exe时,却提示动态库文件无效或损坏,编译所采用指令为:
D:\dlltest>ifort /exe /out:myprogram.exe main.f90 subtest.dll
运行结果如图:
D:\pic.png
想请教具体原因和解决办法,按理来说该dll文件可以在ide中成功调用,应该是正常的?
作者: 一个憎学家    时间: 2024-5-21 16:05
D:\dlltest>ifort /exe /out:myprogram.exe main.f90 subtest.dll
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 14.0.1.139 Build 20131008
Copyright (C) 1985-2013 Intel Corporation.  All rights reserved.
ifort: command line warning #10155: ignoring option '/exe'; argument required
ifort: command line warning #10158: ignoring option '/o'; argument must be separate
ifort: command line warning #10161: unrecognized source type 'subtest.dll'; object file assumed

ipo: warning #11010: file format not recognized for D:\dlltest\subtest.dll
Microsoft (R) Incremental Linker Version 12.00.30501.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:main.exe
-subsystem:console
main.obj
subtest.dll
subtest.dll : fatal error LNK1107: 文件无效或损坏:  无法在 0x2C8 处读取
以上为命令行下的报错,似乎无法发送图片?望海涵。

作者: 楚香饭    时间: 2024-5-21 16:22
ifort /exe /out:myprogram.exe main.f90 subtest.lib
作者: 一个憎学家    时间: 2024-5-22 08:29
楚香饭 发表于 2024-5-21 16:22
ifort /exe /out:myprogram.exe main.f90 subtest.lib

非常感谢,通过静态库可以成功编译生成exe。另外想请教下动态库dll文件无法这样编译和调用吗?
作者: 楚香饭    时间: 2024-5-22 11:21
本帖最后由 楚香饭 于 2024-5-22 11:29 编辑
一个憎学家 发表于 2024-5-22 08:29
非常感谢,通过静态库可以成功编译生成exe。另外想请教下动态库dll文件无法这样编译和调用吗? ...

一样的,静态库导入的 .lib 文件通常就叫“静态库”。
而动态库导入的 .lib 文件通常叫“导入库”,扩展名都是 .lib,比较容易混淆。这个导入库由编译 dll 文件时产生。就是你说的:
成功生成了三个同名的.dll,.lib和.exp文件
这里的 .lib 导入库文件。

(事实上,静态库和导入库没有本质区别,甚至通过某些手段,你可以制作出一个 .lib 文件,它其中一部分函数是静态的,另一部分函数是导入的)

作者: 一个憎学家    时间: 2024-5-22 15:44
楚香饭 发表于 2024-5-22 11:21
一样的,静态库导入的 .lib 文件通常就叫“静态库”。
而动态库导入的 .lib 文件通常叫“导入库”,扩展名 ...

非常感谢





欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2