Calling Fortran DLL from Python

Calling Fortran DLL from Python

I came across an example of calling a Fortran subroutine (in a DLL) from Python that apparently works with CVF. The Fortran and Python files are attached. When I test it with IVF it almost works. The program writes out

2 3.000000 Test56789

which is correct, then the error message:

Traceback (most recent call last):
File "demo.py", line 17, in
mydll.DEMO(byref(rc))
ValueError: Procedure probably called with too many arguments (4 bytes in excess)

I'm guessing this is related to the character variable. What should I do to make this work?

AttachmentSize
Downloadapplication/octet-stream demo.f900 bytes
Downloadimage/jpeg 64301.jpg4.25 KB
14 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

My guess is that Python wants the Fortran routine to be STDCALL.

Steve - Intel Developer Support

Quoting - Steve Lionel (Intel)
My guess is that Python wants the Fortran routine to be STDCALL.

That doesn't seem to work. I added the line
!DEC$ ATTRIBUTES STDCALL, ALIAS:'DEMO' :: demo
(ALIAS needed for demo to be found) and got:

11313288 3.1208767E-39 T! (+ more nonprinting characters)
Traceback (most recent call last):
File "demo.py", line 17, in
mydll.DEMO(byref(rc))
WindowsError: exception: access violation reading 0x2020656C

The arguments (3,2.0,'Test56789') are now not passed correctly.
Using 'C' instead of 'STDCALL' doesn't work either. I feel sure it must be possible to get this to work.

A colleague has suggested that it could be an alignment issue - 8-byte vs. 4-byte boundary - and that there might be a compiler option to overcome this. There are many compiler options.

Quoting - gib
That doesn't seem to work. I added the line
!DEC$ ATTRIBUTES STDCALL, ALIAS:'DEMO' :: demo
(ALIAS needed for demo to be found) and got:

11313288 3.1208767E-39 T! (+ more nonprinting characters)
Traceback (most recent call last):
File "demo.py", line 17, in
mydll.DEMO(byref(rc))
WindowsError: exception: access violation reading 0x2020656C

The arguments (3,2.0,'Test56789') are now not passed correctly.
Using 'C' instead of 'STDCALL' doesn't work either. I feel sure it must be possible to get this to work.

A colleague has suggested that it could be an alignment issue - 8-byte vs. 4-byte boundary - and that there might be a compiler option to overcome this. There are many compiler options.

I find that if I set Fortran > External Procedures > Calling Convention to CVF, the example runs correctly. What are the implications of this change for my real program?

I'm unsure why you asked a follow-on question in comp.lang.fortran - I'm glad to answer here.

What I said earlier was correct, but it's more than just using ATTRIBUTES STDCALL, since that has other effects, mainly, pass-by-value. You could add REFERENCE to the ATTRIBUTES line (!DEC$ ATTRIBUTES STDCALL, REFERENCE :: demo) and that would be sufficient in combination with the existing ALIAS.

To get the full effect of /iface:cvf, use this combination:

!DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, DECORATE, ALIAS:"DEMO" :: demo

You don't want the DECORATE in this case because you don't want a decorated name. I've suggested that the compiler add ATTRIBUTES CVF to do this and this should show up in a future version.

Steve - Intel Developer Support

Quoting - gib
I came across an example of calling a Fortran subroutine (in a DLL) from Python that apparently works with CVF. The Fortran and Python files are attached. When I test it with IVF it almost works. The program writes out

2 3.000000 Test56789

which is correct, then the error message:

Traceback (most recent call last):
File "demo.py", line 17, in
mydll.DEMO(byref(rc))
ValueError: Procedure probably called with too many arguments (4 bytes in excess)

I'm guessing this is related to the character variable. What should I do to make this work?

You might want to try using F2py (part of numpy) which allows you to call fortran code directly from a Python module.

see http://www.scipy.org/F2py

Quoting - Steve Lionel (Intel)
I'm unsure why you asked a follow-on question in comp.lang.fortran - I'm glad to answer here.

What I said earlier was correct, but it's more than just using ATTRIBUTES STDCALL, since that has other effects, mainly, pass-by-value. You could add REFERENCE to the ATTRIBUTES line (!DEC$ ATTRIBUTES STDCALL, REFERENCE :: demo) and that would be sufficient in combination with the existing ALIAS.

To get the full effect of /iface:cvf, use this combination:

!DEC$ ATTRIBUTES STDCALL, REFERENCE, MIXED_STR_LEN_ARG, DECORATE, ALIAS:"DEMO" :: demo

You don't want the DECORATE in this case because you don't want a decorated name. I've suggested that the compiler add ATTRIBUTES CVF to do this and this should show up in a future version.

Thanks Steve. I posted to c.l.f because I was in a hurry to get this sorted out - just impatience, in other words. I was hoping that there would be a combination of ATTRIBUTES, and I'm not disappointed.

BTW, my motivation for this Python-Fortran interface is to explore using Python (+Qt) to build a GUI for my program. I considered using Xeffort, to stay with Fortran, but that would restrict things to Windows. Python, in combination with other open-source tools, looks like a feasible option.

Quoting - tracyx

Quoting - gib
I came across an example of calling a Fortran subroutine (in a DLL) from Python that apparently works with CVF. The Fortran and Python files are attached. When I test it with IVF it almost works. The program writes out

2 3.000000 Test56789

which is correct, then the error message:

Traceback (most recent call last):
File "demo.py", line 17, in
mydll.DEMO(byref(rc))
ValueError: Procedure probably called with too many arguments (4 bytes in excess)

I'm guessing this is related to the character variable. What should I do to make this work?

You might want to try using F2py (part of numpy) which allows you to call fortran code directly from a Python module.

see http://www.scipy.org/F2py

Thanks, I am looking at F2py.

Quoting - gib

Thanks Steve. I posted to c.l.f because I was in a hurry to get this sorted out - just impatience, in other words. I was hoping that there would be a combination of ATTRIBUTES, and I'm not disappointed.

BTW, my motivation for this Python-Fortran interface is to explore using Python (+Qt) to build a GUI for my program. I considered using Xeffort, to stay with Fortran, but that would restrict things to Windows. Python, in combination with other open-source tools, looks like a feasible option.

Gib,

When you've got your GUI working under Python, can you post some details about what you have done, because I am sure there are many of us interested in learning more about new ways of doing this.

Over the years, I have used RealWin (started using withLahey and continued through CVF, DVF to IVF), but is now unsupported; I have started migrating my GUI's to Xeffort, but it is a major job for my main application which has a dozen or more input dialogs with hundreds of input fields.

Thanks,

David

Quoting - David White

Gib,

When you've got your GUI working under Python, can you post some details about what you have done, because I am sure there are many of us interested in learning more about new ways of doing this.

Over the years, I have used RealWin (started using withLahey and continued through CVF, DVF to IVF), but is now unsupported; I have started migrating my GUI's to Xeffort, but it is a major job for my main application which has a dozen or more input dialogs with hundreds of input fields.

Thanks,

David

Certainly David. I will have a student working on this for 10 weeks over our summer, i.e. starting in mid-November. I've just been doing some preliminary reconnaisance. A colleague is very keen about MayaVi
http://en.wikipedia.org/wiki/MayaVi, which he invokes with Python scripts, for 3D graphics. I myself am reluctant to learn yet another language, but it seems almost unavoidable.

Cheers
Gib

I've been doing some GUI stuff in Python recently:

  • F2py to compile my fortran code so it is callable as a python module
  • PyQt4 for the user interface
  • matplotlib to do the visualisation

This works well for me, and it did not take long to learn (coming from a zero python background).

Quoting - tracyx
I've been doing some GUI stuff in Python recently:

  • F2py to compile my fortran code so it is callable as a python module
  • PyQt4 for the user interface
  • matplotlib to do the visualisation

This works well for me, and it did not take long to learn (coming from a zero python background).

Sounds encouraging. Is F2py OK with Fortran95? I'm guessing that there might be limits to the range of permissible subroutine arguments. E.g. can an argument be a pointer?

Gib

Quoting - gib

Sounds encouraging. Is F2py OK with Fortran95? I'm guessing that there might be limits to the range of permissible subroutine arguments. E.g. can an argument be a pointer?

Gib

Yes, it is okay with F95, but there are limitations for arguments. In particular, I do not believe it (yet) supports derived types. As I understand, Python does not have much need for pointers (so that may not be relevant), but things like optional arguments, arrays, etc. are all fine.

I do most my development on Linux, in which case I was able to get F2py to work with ifort 11 without any difficulty at all. On windows I was not able to get ifort 11 working with F2py, but both G95 and gfortran worked no problem.

A introductory guide to F2py which I found useful is here:

http://www-uxsup.csx.cam.ac.uk/courses/PythonFortran/f2py2.pdf

Hope this is useful.

Quoting - tracyx

Quoting - gib
Sounds encouraging. Is F2py OK with Fortran95? I'm guessing that there might be limits to the range of permissible subroutine arguments. E.g. can an argument be a pointer?

Gib

Yes, it is okay with F95, but there are limitations for arguments. In particular, I do not believe it (yet) supports derived types. As I understand, Python does not have much need for pointers (so that may not be relevant), but things like optional arguments, arrays, etc. are all fine.

I do most my development on Linux, in which case I was able to get F2py to work with ifort 11 without any difficulty at all. On windows I was not able to get ifort 11 working with F2py, but both G95 and gfortran worked no problem.

A introductory guide to F2py which I found useful is here:

http://www-uxsup.csx.cam.ac.uk/courses/PythonFortran/f2py2.pdf

Hope this is useful.

Thanks. The difficulty you had with ifort on Windows may have been related to the calling convention issue that Steve resolved for me.

BTW I've done only preliminary investigations but it looks as if I'll be able to do much of what I want just using the ctypes module. If I need to have access to multidimensional arrays in Python then I'll have to get into f2py.

Leave a Comment

Please sign in to add a comment. Not a member? Join today