Fra*_*acq 5 windows dll fortran
我想在Windows上为Fortran项目创建DLL(实际上是Fortran + C).当dll依赖于另一个时,我遇到了麻烦,我在Linux上遇到了麻烦.
这是一个简短的例子:
文件dll1.f90
module dll1
implicit none
contains
subroutine test1
write(*,*) "test1 ok"
end subroutine
end module
Run Code Online (Sandbox Code Playgroud)
文件dll2.f90
module dll2
use dll1,only : test1
implicit none
contains
subroutine test2
call test1
end subroutine
end module
Run Code Online (Sandbox Code Playgroud)
文件main.f90
program main
use dll2, only : test2
implicit none
call test2
end program
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
在Windows上,我在第二条指令处收到第一条错误消息:
对__dll1_MOD_test1的未定义引用(ld消息)
我可以在修改第二条指令时解决这个问题,如下所示:
gfortran -shared -fPIC -o dll2.dll dll2.f90 -L . -ldll1
Run Code Online (Sandbox Code Playgroud)
但由于以下几个原因,这种修改不方便:
如果一个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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:如何解决这些缺点?
在如何为加载时动态链接解析符号方面,两种操作系统之间的理念存在差异.在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
Run Code Online (Sandbox Code Playgroud)
检查dll和exe可执行模块显示预期的符号导入和导出,运行时调试显示正在可执行模块之间传输执行.
请注意,剥离调试符号将极大地减少EXE和DLL文件大小.
| 归档时间: |
|
| 查看次数: |
1056 次 |
| 最近记录: |