M
Mangabasi
Howdy,
I have been trying to call the following Fortran function from Python
(using Windows XP, Compaq Fortran and Python 2.4). I tried F2Py,
Pyfort and calldll with no success.
I think I came very close with calldll. Here is a short summary
Fortran code:
SUBROUTINE SAMPLE(IERR1,IERR2,AIN,AOUT)
C
C SIMPLE SAMPLE OF A DLL
C
!DEC$ATTRIBUTES DLLEXPORT :: SAMPLE
!DEC$ATTRIBUTES ALIAS:'SAMPLE' :: SAMPLE
INTEGER,INTENT(OUT) :: IERR1,IERR2
REAL*8,INTENT(IN) :: AIN(*)
REAL*8,INTENT(OUT) :: AOUT(*)
C
C *** SET MAXIMUM EXPECTED ELEMENTS OF ARRAY AIN AND AOUT
C
PARAMETER (MAXNVIN=101,MAXNVOUT=200)
C
C *** SET ERROR INDICATORS TO ZERO
C
IERR1=0
IERR2=0
C
C *** GET NUMBER OF INPUT VALUES
C
NVIN=AIN(1)
C *** IF NUMBER EXCEEDS MAXIMUM EXPECTED SET ERRORS AND RETURN
IF(NVIN .GT. MAXNVIN) THEN
IERR1=1
IERR2=1
RETURN
ENDIF
C
C *** SET NUMBER OF OUTPUT VALUES
C
NVOUT=2*NVIN
C *** IF NUMBER EXCEEDS MAXIMUM EXPECTED SET ERRORS AND RETURN
IF(NVOUT .GT. MAXNVOUT) THEN
IERR1=1
IERR2=2
RETURN
ENDIF
C
C *** INITIALIZE AOUT INDEX
C
JOUT=0
C
C *** COMPUTE TWO OUTPUT VALUES FOR EACH INPUT VALUE
C
DO I=1,NVIN
JOUT=JOUT+1
AOUT(JOUT)=2.*AIN(I+1)
JOUT=JOUT+1
AOUT(JOUT)=3.*AIN(I+1)
END DO
RETURN
END
compiled it to a dll and called this dll from another Fortran program
with success, so this tells me that dll is OK.
This is how I tried to call it from python 2.4
import calldll
handle = calldll.load_library('c:/sample_dll.dll')
addr = calldll.get_proc_address(handle, 'SAMPLE')
#so far so good, I got a handle and address
e1 = 0
e2 = 0
ain = [2, 3, 4]
aout = [ ]
calldll.call_foreign_function(addr, 'hhll', 'l',(e1, e2,ain,aout))
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: an integer is required
Has anyone provide a similar example with Pyfort, F2Py or calldll?
Thanks in advance.
I have been trying to call the following Fortran function from Python
(using Windows XP, Compaq Fortran and Python 2.4). I tried F2Py,
Pyfort and calldll with no success.
I think I came very close with calldll. Here is a short summary
Fortran code:
SUBROUTINE SAMPLE(IERR1,IERR2,AIN,AOUT)
C
C SIMPLE SAMPLE OF A DLL
C
!DEC$ATTRIBUTES DLLEXPORT :: SAMPLE
!DEC$ATTRIBUTES ALIAS:'SAMPLE' :: SAMPLE
INTEGER,INTENT(OUT) :: IERR1,IERR2
REAL*8,INTENT(IN) :: AIN(*)
REAL*8,INTENT(OUT) :: AOUT(*)
C
C *** SET MAXIMUM EXPECTED ELEMENTS OF ARRAY AIN AND AOUT
C
PARAMETER (MAXNVIN=101,MAXNVOUT=200)
C
C *** SET ERROR INDICATORS TO ZERO
C
IERR1=0
IERR2=0
C
C *** GET NUMBER OF INPUT VALUES
C
NVIN=AIN(1)
C *** IF NUMBER EXCEEDS MAXIMUM EXPECTED SET ERRORS AND RETURN
IF(NVIN .GT. MAXNVIN) THEN
IERR1=1
IERR2=1
RETURN
ENDIF
C
C *** SET NUMBER OF OUTPUT VALUES
C
NVOUT=2*NVIN
C *** IF NUMBER EXCEEDS MAXIMUM EXPECTED SET ERRORS AND RETURN
IF(NVOUT .GT. MAXNVOUT) THEN
IERR1=1
IERR2=2
RETURN
ENDIF
C
C *** INITIALIZE AOUT INDEX
C
JOUT=0
C
C *** COMPUTE TWO OUTPUT VALUES FOR EACH INPUT VALUE
C
DO I=1,NVIN
JOUT=JOUT+1
AOUT(JOUT)=2.*AIN(I+1)
JOUT=JOUT+1
AOUT(JOUT)=3.*AIN(I+1)
END DO
RETURN
END
compiled it to a dll and called this dll from another Fortran program
with success, so this tells me that dll is OK.
This is how I tried to call it from python 2.4
import calldll
handle = calldll.load_library('c:/sample_dll.dll')
addr = calldll.get_proc_address(handle, 'SAMPLE')
#so far so good, I got a handle and address
e1 = 0
e2 = 0
ain = [2, 3, 4]
aout = [ ]
calldll.call_foreign_function(addr, 'hhll', 'l',(e1, e2,ain,aout))
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: an integer is required
Has anyone provide a similar example with Pyfort, F2Py or calldll?
Thanks in advance.