All,
I’m very new to Python, and C/C++ for that matter… I’ve been a Fortran programmer since the dawn of time, in an environment that didn’t really require expertise in interoperability with other languages. Times have changed!
I’m trying to build a Python script that accesses array data from a foreign language library (a Fortran DLL) that dynamically allocates memory for the array of interest. I gather from various online searches that this is not trivial to do, if even possible.
The Fortran function discussed here is a simplified example of the one I actually need to integrate with a Python script. But if I can get this example to work, I can make the real one work. The constraint is that the Fortran library itself is immutable… either it works as-is, or it doesn’t.
Although this is a Python forum, I’ll include the Fortran code here for completeness. It’s a simple function that fills an array whose size is initially undertermined:
Integer Function SimpleDLL(OutInt,OutArray) Bind(C, name="SimpleDLL")
USE, INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE
!DIR$ ATTRIBUTES DLLEXPORT :: SimpleDLL
Integer(C_INT), INTENT(OUT) :: OutInt
Real(C_FLOAT), Allocatable, INTENT(OUT) :: OutArray(:)
Real :: r,sum
Integer :: i,j
i = 0
sum = 0
Call RANDOM_SEED()
Do While (sum <= 5)
Call RANDOM_NUMBER(r)
sum = sum + r
i = i + 1
EndDo
Allocate(OutArray(i))
Do j = 1,i
OutArray(j) = FLOAT(j)**(i/5.)
EndDo
OutInt = i
SimpleDLL = 5/i
End Function SimpleDLL
The above is compiled into a DLL that is interoperable with C via the BIND(C) directive (and hence, in principle, is interoperable with Python). I have verified that this DLL can be succesfully called from a Fortran driver that declares the function argument corresponding to OutArray to be an allocatable C_FLOAT array.
This is my attempt to call this DLL function from a Python script (I’m also not at all fluent with ctypes!):
# Python script that calls SimpleDLL
import ctypes as ct
import numpy as np
# import the dll
flib = ct.CDLL('./SimpleDLL.dll')
# declare the DLL function's result type
flib.SimpleDLL.restype = ct.c_int
# define argument types
c_int_p = ct.POINTER(ct.c_int)
c_float_p = ct.POINTER(ct.c_float)
# initialize arguments
InInt = ct.c_int(0)
InArray = ct.c_float()
# call the DLL function
result = flib.SimpleDLL(ct.byref(InInt), ct.byref(InArray))
# show the results
print('Result = ',result)
print('Array Size = ' + str(InInt.value))
print('Array = ' + str(InArray.value))
The output for a typical execution of this script is:
Result = 0
Array Size = 11
Array = 5.925913876308824e-33
The script is evidently communicating with the DLL (I successfully get back the function result and the array size), but what I really need is the data in the returned array, which I clearly don’t know how to extract. Is it even possible from Python? Thanks for any info-