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

A

alex

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@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>
 
J

Jon Clements

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@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
 
A

alex

Jon
Thank you for your answer. I tried it with no success.

However I tried with
tst=cdll.LoadLibrary("f:\\scratch\\test2\\footst.dll") instead of
tst=windll.LoadLibrary("f:\\scratch\\test2\\footst.dll")

and it runs now with no error message, I can't figure for now why, but
it's great! This is motivating for going ahead.

Regards Alex
 
A

alex

Duncan
Thank you for your explanation of the relationship between calling
convention and stack management.
I will try to understand better this topic in the CVF and ctypes
documentation (not so easy).

Regards Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,152
Members
46,698
Latest member
LydiaHalle

Latest Threads

Top