gpt4 book ai didi

windows - 在 Windows 上使用 gfortran 创建 DLL

转载 作者:可可西里 更新时间:2023-11-01 13:31:07 27 4
gpt4 key购买 nike

我想在 Windows 上为 Fortran 项目(实际上是 Fortran+C)创建 DLL。当一个 dll 依赖于另一个 dll 时,我遇到了在 Linux 上没有遇到的麻烦。

这是一个简短的例子:

文件dll1.f90

module dll1
implicit none
contains
subroutine test1
write(*,*) "test1 ok"
end subroutine
end module

文件dll2.f90

module dll2
use dll1,only : test1
implicit none
contains
subroutine test2
call test1
end subroutine
end module

文件 main.f90

program main
use dll2, only : test2
implicit none
call test2
end program

Linux 命令(文件 run.bash)

gfortran -shared -fPIC -o libdll1.so dll1.f90
gfortran -shared -fPIC -o libdll2.so dll2.f90
gfortran -o main.exe main.f90 -I. -L. -ldll2 -ldll1
export LD_LIBRARY_PATH="./"
./main.exe

Windows 命令(文件 run.bat)

gfortran -shared -fPIC -o dll1.dll dll1.f90
gfortran -shared -fPIC -o dll2.dll dll2.f90
gfortran -o main.exe main.f90 -I. -L. -ldll2 -ldll1
.\main.exe

在 Windows 上,我在第二条指令处收到第一条错误消息:

undefined reference to __dll1_MOD_test1 (ld message)

我可以通过如下修改第二条指令来解决这个问题:

gfortran -shared -fPIC -o dll2.dll dll2.f90 -L . -ldll1

但由于以下几个原因,这种修改并不方便:

  • 如果一个dll依赖于很多dll,那么它的体积会变得非常大(好像包含了所有的子dll)

  • 可执行程序的体积也很大

  • 我使用经典库而不是 dll 得到了更合理的结果

Linux 文件大小:

[coul@localhost dll]$ ls -al
total 68
drwxrwxr-x 2 coul coul 4096 29 déc. 12:09 .
drwxrwxr-x. 7 coul coul 4096 29 déc. 11:46 ..
-rw-rw-r-- 1 coul coul 118 29 déc. 11:25 dll1.f90
-rw-rw-r-- 1 coul coul 204 29 déc. 12:09 dll1.mod
-rw-rw-r-- 1 coul coul 132 29 déc. 11:29 dll2.f90
-rw-rw-r-- 1 coul coul 237 29 déc. 12:09 dll2.mod
-rwxrwxr-x 1 coul coul 8184 29 déc. 12:09 libdll1.so
-rwxrwxr-x 1 coul coul 7920 29 déc. 12:09 libdll2.so
-rwxrwxr-x 1 coul coul 8712 29 déc. 12:09 main.exe
-rw-rw-r-- 1 coul coul 82 29 déc. 11:27 main.f90
-rwxrwxr-x 1 coul coul 183 29 déc. 11:38 run.bash
-rw-rw-r-- 1 coul coul 151 29 déc. 11:55 run.bat

Windows 文件大小

29/12/2017  11:53    <DIR>          .
29/12/2017 11:53 <DIR> ..
29/12/2017 11:53 2 264 764 dll1.dll
29/12/2017 11:25 118 dll1.f90
29/12/2017 11:50 204 dll1.mod
29/12/2017 11:53 51 814 dll2.dll
29/12/2017 11:29 132 dll2.f90
29/12/2017 11:50 237 dll2.mod
29/12/2017 11:53 2 264 671 main.exe
29/12/2017 11:27 82 main.f90
29/12/2017 11:38 183 run.bash
29/12/2017 11:53 162 run.bat

所以我的问题是:如何解决这些缺点?

最佳答案

就加载时动态链接的符号解析方式而言,这两个操作系统在理念上存在差异。在 Linux 中,提供特定符号的库名称的解析可以推迟到加载时进行,而在 Windows 中,提供符号的库名称必须在链接时解析。

因此,在 linux 下,您可以链接 libdll2.so 共享库,而无需向链接器提供有关 test1 过程的目标代码位置的任何信息,而在 Windows 上链接 dll2 需要类似于 -ldll1 的内容 命令选项。在 Windows 上链接最终的可执行文件时,您不需要重复 -ldll1 规范。

我无法使用 Msys2 mingw-64 x86_64 工具链在 Windows 上通过修改后的链接过程重现您的观察结果。

$ gfortran -shared -fPIC -o dll1.dll dll1.f90
$ gfortran -shared -fPIC -o dll2.dll dll2.f90 -L. -ldll1
$ gfortran -o main main.f90 -L. -ldll2
$ ./main.exe
test1 ok

$ du -b *
330013 dll1.dll
125 dll1.f90
204 dll1.mod
329573 dll2.dll
140 dll2.f90
237 dll2.mod
398054 main.exe
87 main.f90

dll 和 exe 可执行模块的检查显示预期的符号导入和导出,运行时调试显示执行正在可执行模块之间转移。

请注意,剥离调试符号会显着减少 EXE 和 DLL 文件的大小。

关于windows - 在 Windows 上使用 gfortran 创建 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48021991/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com