2017-12-29 53 views
3

Windows에서 Fortran 프로젝트 (사실 Fortran + C) 용 DLL을 생성하고 싶습니다. dll이 다른 DLL에 의존 할 때 Linux에서 만나지 않는 문제가 발생합니다.Windows에서 gfortran을 사용하여 DLL을 생성하십시오.

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 

리눅스 명령

파일 dll1.f90 (: 여기

짧은 예이다 파일 실행. 배시)

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.bat를) Windows에서

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 

, 나는 두 번째 명령에서 첫 번째 오류 메시지가 명령 :

__dll1_MOD_test1 (LD 메시지)에 정의되지 않은 참조

I은 ​​제 2 명령과 같은 수정이 문제를 해결할 수있다

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

을하지만이 수정이 여러 가지 이유로 편리하지 않습니다 : 다음

  • dll을 여러 DLL을에 의존하는 경우

    , 그때 그 크기가 매우 큰이된다 (모든 하위 DLL을 포함 할 것)

  • 실행 프로그램의 크기가 큰뿐만 아니라

  • 내가 고전 라이브러리를 사용하여 훨씬 더 합리적인 결과를 얻을 수있다

리눅스 파일 크기 DLL을 대신 :

[[email protected] 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 

그래서 제 질문은 : 이러한 단점을 해결하는 방법을?

답변

3

기호는로드시 동적 링크에 대한 해결 방법의 측면에서 두 운영 체제 사이의 철학에 차이가 있습니다. 리눅스에서는 특정 심볼을 제공하는 라이브러리 이름의 해상도가로드 시간까지 지연 될 수 있지만 Windows에서는 심볼을 제공 할 라이브러리의 이름이 링크 타임에 해결되어야합니다.

결과적으로 Windows에서 dll2를 연결하는 동안 -ldll1 명령 옵션과 비슷한 것이 필요하지만 Linux에서는 test1 절차의 개체 코드 위치에 대한 정보를 링커에 제공하지 않고 libdll2.so 공유 라이브러리를 연결할 수 있습니다.Windows에서 최종 실행 파일을 링크 할 때 -ldll1 스펙을 반복 할 필요가 없습니다.

Windows에서 Msys2 mingw-64 x86_64 도구 체인을 사용하여 수정 된 링크 프로세스로 관측치를 재현 할 수 없습니다. DLL이 EXE 및 실행 모듈

$ 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 

검사 예상 심볼 수출입 표시 및 런타임 디버깅은 실행이 실행 모듈 사이에서 전송되는 나타낸다.

디버깅 기호를 제거하면 EXE 및 DLL 파일 크기가 현저히 줄어 듭니다.