Le code suivant est compilé en 64 bits mais l'utilisation des interfaces génériques Fortran semble confondre l'attribut gcc en 32 bits (requis pour appeler l'API STDCALL 32 bits). Le code est une version allégée du projet f03gl que je tente de construire pour Windows (je ne pouvais pas créer un repro plus petit).Est-ce que cette erreur de l'éditeur de liens dans Windows 32 bits gFortran un bug?
Un remaniement du code (affiché en bas) sans l'interface générique et le passage direct des arguments compile et fonctionne. J'espère que je n'aurai pas à réécrire tous les appels pour contourner ce problème.
L'erreur est;
callglutbad.o:callglutbad.f90:(.text+0x27): undefined reference to `glutInit'
callglut.f90 (compilation échoue 32 bits)
MODULE GlutModule
USE ISO_C_BINDING
IMPLICIT NONE
PUBLIC glutInit
INTERFACE glutInit
MODULE PROCEDURE glutInit_f03
END INTERFACE glutInit
INTERFACE
SUBROUTINE glutInit_gl(pargc, argv) BIND(C,NAME="glutInit")
IMPORT
#ifdef x86
!GCC$ ATTRIBUTES stdcall :: glutInit
#endif
INTEGER(C_INT) :: pargc
TYPE(C_PTR), INTENT(IN) :: argv
END SUBROUTINE glutInit_gl
END INTERFACE
CONTAINS
SUBROUTINE glutInit_f03()
INTEGER(C_INT) :: argcp=1
TYPE(C_PTR), DIMENSION(1), TARGET :: argv=C_NULL_PTR
CHARACTER(C_CHAR), DIMENSION(1), TARGET :: empty_string=C_NULL_CHAR
argv(1)=C_LOC(empty_string)
CALL glutInit_gl(argcp, C_LOC(argv))
END SUBROUTINE
END MODULE GlutModule
program main
USE GlutModule
PRINT *,"Calling glutInit"
call glutInit()
PRINT *,"Called glutInit"
end program main
build.bat
REM 32 bit
@setlocal
@SET PATH=%PATH%;C:\msys64\mingw32\bin\
gfortran -Dx86 -cpp -c callglut.f90 -o callglut.o
gcc callglut.o -o callglut32.exe ..\x86\lib\freeglut.lib -lgfortran
@endlocal
REM 64 bit
@setlocal
@SET PATH=%PATH%;C:\msys64\mingw64\bin\
gfortran -cpp -c callglut.f90 -o callglut.o
gcc callglut.o -o callglut64.exe ..\x64\lib\freeglut.lib -lgfortran
@endlocal
L'interface générique est utilisée pour appeler glutInit sans paramètres de Fortran (les paramètres sont renseignés par le sous-programme proxy).
callglut.f90 (compile et fonctionne sur les plates-formes)
MODULE GlutModule
USE ISO_C_BINDING
IMPLICIT NONE
PUBLIC glutInit
INTERFACE
SUBROUTINE glutInit(pargc, argv) BIND(C,NAME="glutInit")
IMPORT
#ifdef x86
!GCC$ ATTRIBUTES stdcall :: glutInit
#endif
INTEGER(C_INT) :: pargc
TYPE(C_PTR), INTENT(IN) :: argv
END SUBROUTINE glutInit
END INTERFACE
END MODULE GlutModule
program main
USE GlutModule
PRINT *,"Calling glutInit"
call glutInit(0,C_NULL_PTR)
PRINT *,"Called glutInit"
end program main
que je vois un bug du compilateur avec l'instruction attribut ne pas être appliqué à une interface générique ou est-ce que je fais ? Je pense que ceci et le changement de nom STDCALL 32 bits de glutInit à _glutInit @ 8 n'est pas effectué. J'utilise gfortran sous msys2 (GNU Fortran (Rev2, Construit par le projet MSYS2) 7.1.0) sur Windows 64 bits avec les deux compilateurs 32 et 64 bits.
Merci, je me suis cogné la tête contre un mur à ce sujet. J'ai supposé que le nom après :: était pour le nom exporté de la bibliothèque, pas le nom local. Assez confus. Avez-vous de bonnes références à ce sujet, car je trouve encore confus? –
Je ne suis pas sûr de ce que vous entendez par "nom exporté de bibliothèque". Les directives du compilateur de gfortran sont documentées sur https://gcc.gnu.org/onlinedocs/gfortran/GNU-Fortran-Compiler-Directives.html – IanH