ctypes with Compaq Visual Fortran 6.6B *.dll (Windows XP), passing of integer and real values

Jon Clements joncle at googlemail.com
Wed Jan 28 00:08:08 CET 2009


On Jan 27, 9:41 pm, alex <ale... at bluewin.ch> wrote:
> Hello everybody
> I am mainly a Fortran programmer and beginning to learn Python(2.5)
> and OOP programming.
> I hope in the end to put a GUI on my existing Fortran code.
> Therefore I am also trying to learn Python's "ctypes" library.
>
> Unfortunately the ctypes tutorial does not show simple examples so I
> set up a simple fortran module
> and Python script to test.
> But even with passing Integer and Real values I get the right output
> but with subsequent error:
> ValueError: Procedure probably called with too many arguments (4 bytes
> in excess)
> The scripts exits then, so the second subroutine call does not happen.
>
> From reading comp.lang.python and comp.lang.fortran I understood that
> passing character strings
> may not be simple but I could not find any solution to my problem.
> Maybe somebody can help me with solving it?
>
> The Fortran module (footst.f90):
>
> !
>       module footst
> !
>       implicit none
> !
> !
> !- End of module header
> ------------------------------------------------
> !
> !- Execution part of the module
> ----------------------------------------
> !
> !
>       contains
> !- Define procedures contained in this module.
> !
> !-----------------------------------------------------------------------
> !
> !
>       subroutine foo1(int_tst)
>       !DEC$ ATTRIBUTES DLLEXPORT :: foo1
>       integer, intent(in):: int_tst
>       write(unit=*, fmt="(a)") "Subroutine foo1(int_tst)"
>       write(unit=*, fmt="(a, i4)") "a= ", int_tst
>       end subroutine foo1
> !
> !
>       subroutine foo2(real_tst)
>       !DEC$ ATTRIBUTES DLLEXPORT :: foo2
>       real, intent(in):: real_tst
>       write(unit=*, fmt="(a)") "Subroutine foo2(real_tst)"
>       write(unit=*, fmt="(a, f6.2)") "a= ", real_tst
>       end subroutine foo2
> !
> !
>       end module footst
> !
>
> The Python script (footst.py):
>
> #!/usr/bin/env python
> #
> #
> from ctypes import *
> #
> #
> if __name__ == '__main__':
>     tst=windll.LoadLibrary("f:\\scratch\\test2\\footst.dll")
> #    tst.restype=None
> #    tst.argtypes=(c_int)
>     x=c_int(999)
>     y=c_float(10.5)
>     tst.footst_mp_foo1_(byref(x))
> #    Passing Real values commented out, but leads to the same error
> #    tst.footst_mp_foo2_(byref(y))
> #
>     main()
> #
> #
>
> The DOS prompt output:
>
> F:\Scratch\Test2>df /dll /iface=(cref,nomixed_str_len_arg)/
> names:lowercase /assume:underscore footst.f90
> Compaq Visual Fortran Optimizing Compiler Version 6.6 (Update B)
> Copyright 2001 Compaq Computer Corp. All rights reserved.
>
> footst.f90
> Microsoft (R) Incremental Linker Version 6.00.8447
> Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
>
> /entry:_DllMainCRTStartup at 12
> /ignore:505
> /debugtype:cv
> /debug:minimal
> /pdb:none
> F:\SysTemp\obj5B.tmp
> dfordll.lib
> msvcrt.lib
> dfconsol.lib
> dfport.lib
> kernel32.lib
> /out:footst.dll
> /dll
>    Creating library footst.lib and object footst.exp
>
> F:\Scratch\Test2>dumpbin /exports footst.dll
> Microsoft (R) COFF Binary File Dumper Version 6.00.8447
> Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
>
> Dump of file footst.dll
>
> File Type: DLL
>
>   Section contains the following exports for footst.dll
>
>            0 characteristics
>     497F5CC3 time date stamp Tue Jan 27 20:13:07 2009
>         0.00 version
>            1 ordinal base
>            2 number of functions
>            2 number of names
>
>     ordinal hint RVA      name
>
>           1    0 00001000 footst_mp_foo1_
>           2    1 000010A6 footst_mp_foo2_
>
>   Summary
>
>         1000 .data
>         1000 .rdata
>         1000 .reloc
>         1000 .text
>
> F:\Scratch\Test2>footst.py
> Subroutine foo1(int_tst)
> a=  999
> Traceback (most recent call last):
>   File "F:\Scratch\Test2\footst.py", line 13, in <module>
>     tst.footst_mp_foo1_(byref(x))
> ValueError: Procedure probably called with too many arguments (4 bytes
> in excess)
>
> F:\Scratch\Test2>

Have you tried:
    tst.footst_mp_foo1_.restype = None
    tst.footst_mp_foo1_(byref(x))

IIRC, the restype is applied to each function, not the library module.

good luck,
Jon



More information about the Python-list mailing list