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-