在Windows上使用gfortran创建DLL [英] creating DLL with gfortran on Windows

查看:343
本文介绍了在Windows上使用gfortran创建DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to create DLLs on windows for a Fortran project (in fact Fortran+C). I get a trouble I do not meet on Linux when a dll depends on another one.

这里是一个简短的示例:

Here is a short example :

文件dll1.f90

file dll1.f90

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

文件dll2.f90

file dll2.f90

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

文件main.f90

File main.f90

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

Linux命令(文件run.bash)

Linux commands (file 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)

Windows commands (file 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上,我得到第一个错误消息在第二条指令上:

On Windows, I get the first error message at the second instruction :


对__dll1_MOD_test1的未定义引用(ld消息)

undefined reference to __dll1_MOD_test1 (ld message)

我可以通过修改第二条指令来解决此问题,如下所示:

I can solve this trouble in modifying the second instruction as follows :

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

但是由于某些原因,这种修改并不方便:

But this modification is not convenient for several reasons :


  • 如果一个dll依赖于许多dll,则它的大小将变得很大(它似乎包含所有子dll)

  • if a dll depends on many dlls, then its size becomes very large (it seems to contain all the sub dlls)

可执行程序的大小也很大

the size of the executable program is large as well

使用经典库而不是dll,我得到的结果要合理得多。 / p>

I get a much more reasonable result using classical libraries instead of dlls

Linux文件大小:

Linux file sizes :

[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文件大小

Windows file sizes

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

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

So my question is : how to solve these drawbacks ?

推荐答案

在两种操作系统之间,在符号解析方式方面存在差异用于加载时间动态链接。在Linux中,提供特定符号的库名称的解析可以推迟到加载时,而在Windows中,提供符号的库名称必须在链接时解析。

There is a difference in philosophy between the two operating systems in terms of how symbols are resolved for load time dynamic linking. In linux, the resolution of the name of the library that provides a particular symbol can be deferred till load time, while in Windows the name of the library that will provide a symbol must be resolved at link time.

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

Consequently, under linux you can link the libdll2.so shared library without providing any information to the linker about the location of the object code for the test1 procedure, while linking dll2 on Windows requires something akin to the -ldll1 command option. When linking the final executable on Windows, you then do not need to repeat the -ldll1 specification.

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

I cannot reproduce your observations with the modified link process on Windows with the Msys2 mingw-64 x86_64 toolchain.

$ 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可执行模块的检查显示了预期的符号导入和导出,并且运行时调试显示执行在

Inspection of the dll and exe executable modules show the expected symbol imports and exports, and runtime debugging shows that execution is being transferred between executable modules.

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

Note that stripping debugging symbols will spectacularly reduce EXE and DLL file size.

这篇关于在Windows上使用gfortran创建DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆