Calling Fortran from Python

Mangabasi mangabasi at gmail.com
Thu Apr 5 09:05:47 EDT 2007


On Apr 4, 10:10 pm, Lenard Lindstrom <l... at telus.net> wrote:
> Mangabasi wrote:
> > On Apr 4, 5:48 pm, Robert Kern <robert.k... at gmail.com> wrote:
> >> Mangabasi wrote:
> >>> Would Python 2.5 work with Visual Studio 6.6?
> >> No.
>
> >> --
> >> Robert Kern
>
> >> "I have come to believe that the whole world is an enigma, a harmless enigma
> >>  that is made terrible by our own mad attempt to interpret it as though it had
> >>  an underlying truth."
> >>   -- Umberto Eco
>
> > I will try the GCC then.  It is a shame that I could not get calldll
> > to work.  It was very simple to use.  I think I am making a mistake
> > with the argument types but not sure.
>
> > Thanks for your help, it is greatly appreciated.
>
> Did you try ctypes?
>
>  >>> from ctypes import *
>  >>> sample=cdll.sample.sample_
>  >>> sample.restype=None
>  >>> sample.argtypes=[POINTER(c_int), POINTER(c_int), POINTER(c_double),
> POINTER(c_double)]
>  >>> e1 = c_int(0)
>  >>> e2 = c_int(0)
>  >>> ain = (c_double*3)(2.0, 3.0, 4.0)
>  >>> aout = (c_double*4)()
>  >>> sample(e1, e2, ain, aout)
>  >>> aout[:]
> [6.0, 9.0, 8.0, 12.0]
>  >>> e1.value
> 0
>  >>> e2.value
> 0
>
> I compile the SAMPLE example with mingw g77 3.4.5:
>
> g77 -shared -o sample.dll sample.for
>
> I had to take out the "INTENT(OUT)"s because g77 didn't like them. And
> "SAMPLE" became "sample_" in the dll. Also note that argument passing to
> Fortran subroutines is strictly pass-by-reference. Thus the ain pointer.
>
> Lenard Lindstrom- Hide quoted text -
>
> - Show quoted text -

Lenard,

Now I tried it as you suggested.  I did not install G77 yet.  I tried
it with the dll I already had.  Something interesting happened:

>>> from ctypes import *
>>> sample=cdll.sample_dll.SAMPLE
>>> sample.restype=None
>>> sample.argtypes=[POINTER(c_int), POINTER(c_int), POINTER(c_double), POINTER(c_double)]
>>> sample.argtypes=[POINTER(c_int), POINTER(c_int), POINTER(c_double), POINTER(c_double)]
>>> e1 = c_int(-10)
>>> e2 = c_int(-10)
>>> ain = (c_double*3)(2.0, 3.0, 4.0)
>>> ain = (c_double*3)(2.0, 3.0, 4.0)
>>> aout = (c_double*4)()
>>> aout = (c_double*4)()
>>> sample(e1, e2, ain, aout)
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
ValueError: Procedure called with not enough arguments (16 bytes
missing) or wrong calling convention
>>> aout[:]
[6.0, 9.0, 8.0, 12.0]

I got an error message and the expected answer!  Any guesses?




More information about the Python-list mailing list