Fortran-compiled DLLs in Python

B

byte biscuit

Hi there everybody!
The problem is the following:
we have a DLL (H2O.dll) - compiled in Visual Fortran - depending in turn on
another DLL.
H2O.dll contains only one (1) function, with a known name (WATER).
The WATER function is called with the following parameters:
- TT (datatype: double precision) [input]
- PP (datatype: double precision) [input]
- State (datatype: integer)
[input]
- DiERR (datatype: integer)
[output]
- SIG (datatype: double precision)
[output]
- Prop (datatype: double precision array[16 elements]) [output]

Obviously, we would like to make use of Python to handle the function and
pick out the results...
We thought of using the **ctypes** module to tackle the problem, but we have
stranded just about at the first attempt:
h2o.WATER(c_long(40.0),c_long(1.0),c_int(2),c_int(dierr),c_int(Sig),c_long*1
6(prop))
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: int expected instead of float instance

Who can show us the Right way, riding the Python? THANKS!

stephen
 
T

Thomas Heller

byte biscuit said:
Hi there everybody!
The problem is the following:
we have a DLL (H2O.dll) - compiled in Visual Fortran - depending in turn on
another DLL.
H2O.dll contains only one (1) function, with a known name (WATER).
The WATER function is called with the following parameters:
- TT (datatype: double precision) [input]
- PP (datatype: double precision) [input]
- State (datatype: integer)
[input]
- DiERR (datatype: integer)
[output]
- SIG (datatype: double precision)
[output]
- Prop (datatype: double precision array[16 elements]) [output]

Obviously, we would like to make use of Python to handle the function and
pick out the results...
We thought of using the **ctypes** module to tackle the problem, but we have
stranded just about at the first attempt:
h2o.WATER(c_long(40.0),c_long(1.0),c_int(2),c_int(dierr),c_int(Sig),c_long*1
6(prop))
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: int expected instead of float instance

Looking at your function description above, I would guess you have call
it in the following way (although the error you get is that c_long(40.0)
complains about the float argument):

dierr = c_int()
prop = (c_double * 16)() # create a 16 element double array

h2o.WATER(c_double(40.0), c_double(1.0), c_int(2),
byref(dierr), prop)

Although I do know nothing about fortran (anymore).

Thomas
 
L

Luca Simonetti

Hi Thomas!
an answer from the true creator of the ctypes module - nice!
anyway, we tried implementing your solution and got the following
Traceback Error:

Traceback (most recent call last):
File "<interactive input>", line 1, in ?
WindowsError: exception: access violation

which would seem to be the classical exception raised through a failed
function call...?

allthebest

luca (+stephen)
 
T

Thomas Heller

byte biscuit said:
Hi there everybody!
The problem is the following:
we have a DLL (H2O.dll) - compiled in Visual Fortran - depending in turn on
another DLL.
H2O.dll contains only one (1) function, with a known name (WATER).
The WATER function is called with the following parameters:
- TT (datatype: double precision) [input]
- PP (datatype: double precision) [input]
- State (datatype: integer)
[input]
- DiERR (datatype: integer)
[output]
- SIG (datatype: double precision)
[output]
- Prop (datatype: double precision array[16 elements]) [output]

Obviously, we would like to make use of Python to handle the function and
pick out the results...
We thought of using the **ctypes** module to tackle the problem, but we have
stranded just about at the first attempt:
h2o.WATER(c_long(40.0),c_long(1.0),c_int(2),c_int(dierr),c_int(Sig),c_long*1
6(prop))
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: int expected instead of float instance

Who can show us the Right way, riding the Python? THANKS!

stephen

Luca Simonetti said:
Hi Thomas!
an answer from the true creator of the ctypes module - nice!
anyway, we tried implementing your solution and got the following
Traceback Error:


Traceback (most recent call last):
File "<interactive input>", line 1, in ?
WindowsError: exception: access violation

which would seem to be the classical exception raised through a failed
function call...?

This is the classical GP fault, which would normally crash a program.
ctypes catches it, but doesn't give more information (in current CVS, it
would have informed you about which memory location could not be written
or read, but that would probably not help you very much).
- Prop (datatype: double precision array[16 elements]) [output]

I do not know how fortran passes this parameter, in the example code I
posted I assumed that the caller allocates an array, passes a pointer to
it to fortran, and the fortran code fills in the elements.

Do you have C sample code that works?

Thomas
 
D

Dennis Lee Bieber

Hi Thomas!
an answer from the true creator of the ctypes module - nice!
anyway, we tried implementing your solution and got the following
Traceback Error:


Traceback (most recent call last):
File "<interactive input>", line 1, in ?
WindowsError: exception: access violation

C passes by value, and to get a "modifiable" argument, the
programmer has to explicitly pass an address (as the value) and then,
also, explicitly dereference through the value.

Traditionally, FORTRAN passes ALL arguments by address, not
value. This may vary a bit in more modern implementations -- character
strings may pass a "string descriptor", which is a structure containing
the address of the string (as normal) along with an added word
containing the size of the space allocated for the string.

I suspect you need to use byref() on all of the arguments.

--
 
B

byte biscuit

I feel we're getting there...

recapitulating:
access violation error:
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
WindowsError: exception: access violation

which in fact - Dennis - is caused by non-referencing, because:
prop)
returns without error.

It is interesting (for me, that is) to note that prop in fact does NOT need
referencing, whereas all other variables (input&output) DO. But, the
returned answer is:

0

which shouldn't be of course............... so there does seem to be a
problem in the definition/passing of the prop parameter, I would say?

stephen


Thomas Heller said:
This is the classical GP fault, which would normally crash a program.
ctypes catches it, but doesn't give more information (in current CVS, it
would have informed you about which memory location could not be written
or read, but that would probably not help you very much).
- Prop (datatype: double precision array[16 elements]) [output]

I do not know how fortran passes this parameter, in the example code I
posted I assumed that the caller allocates an array, passes a pointer to
it to fortran, and the fortran code fills in the elements.

Do you have C sample code that works?

Thomas
C passes by value, and to get a "modifiable" argument, the
programmer has to explicitly pass an address (as the value) and then,
also, explicitly dereference through the value.

Traditionally, FORTRAN passes ALL arguments by address, not
value. This may vary a bit in more modern implementations -- character
strings may pass a "string descriptor", which is a structure containing
the address of the string (as normal) along with an added word
containing the size of the space allocated for the string.

I suspect you need to use byref() on all of the arguments.

--
 
D

Dennis Lee Bieber

It is interesting (for me, that is) to note that prop in fact does NOT need
referencing, whereas all other variables (input&output) DO. But, the
returned answer is:
Okay, my "all" was a bit over done... Since C normally passes
(as a value) the address of the first element, that already matched what
FORTRAN expected.
0

which shouldn't be of course............... so there does seem to be a
problem in the definition/passing of the prop parameter, I would say?
I suspect the declaration...

code> prop = (c_double * 16)()

I've not used ctypes, so I don't fully understand the above, but
it looks very much like it is making 16 copies of the c_double FUNCTION,
and then invoking this "array" with no arguments. The closest thing I
find in the ctypes tutorial page implies you don't want the trailing ()

stephen


Thomas Heller said:
This is the classical GP fault, which would normally crash a program.
ctypes catches it, but doesn't give more information (in current CVS, it
would have informed you about which memory location could not be written
or read, but that would probably not help you very much).
- Prop (datatype: double precision array[16 elements]) [output]

I do not know how fortran passes this parameter, in the example code I
posted I assumed that the caller allocates an array, passes a pointer to
it to fortran, and the fortran code fills in the elements.

Do you have C sample code that works?

Thomas
C passes by value, and to get a "modifiable" argument, the
programmer has to explicitly pass an address (as the value) and then,
also, explicitly dereference through the value.

Traditionally, FORTRAN passes ALL arguments by address, not
value. This may vary a bit in more modern implementations -- character
strings may pass a "string descriptor", which is a structure containing
the address of the string (as normal) along with an added word
containing the size of the space allocated for the string.

I suspect you need to use byref() on all of the arguments.

--
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top