Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Getting allocated data out of Fortran-Dll and back in again

Tobias_Loew
Novice
276 Views

Hi,

I've got a Fortran-Dll which will be used by all kind of other programs (e.g. Excel-VBA, Python, C/C++ programs).

The Fortran-Dll is stateless (i.e. no static-variables, SAVE or DATA). All data is either on the stack or dynamically allocated, thus the dll can be used parallel without restrictions. (OpenMP is NOT used since it reduces the parallelization to OpenMP-threads only).

Let's assume there is an exported function CALCULATE from the dll. On each call CALCULATE allocates a large user-defined structure, initializes it, makes some calculations and returns the result AND deallocates the user-defined structure again.

Since the initialization of the user-defined structure is quite complex, I would like to re-use it for multiple calls to CALCULATE. Below is a sketch of my current approach to this (returning the address of the user-defined structure to the caller)

My question is: Is there any other/better or even standardized way to export Fortran allocated data?

Tobias

 

integer(c_intptr_t) function CREATE_DATA (arg_1, ... , arg_n)          
!DEC$ ATTRIBUTES DLLEXPORT::CREATE_DATA
useintrinsic :: iso_c_binding
implicit none
    type(large_udt),pointer :: data
    allocate(data)
 
      ! use arg_1,...,arg_n to initialize  data
      ! call setup(data, arg_1,...,arg_n) 
     CREATE_DATA = LOC(data)
end function CREATE_DATA
    

subroutine DESTROY_DATA (handle)
!DEC$ ATTRIBUTES DLLEXPORT::DESTROY_DATA
useintrinsic :: iso_c_binding
implicit none
    integer(c_intptr_t), intent(in)  :: handle 
    type(type_udt),target :: data
    type(type_udt),pointer :: data_ptr
 
    pointer(handle,data)
    data_ptr => data
    deallocate(data_ptr)
 end subroutine DESTROY_DATA

 

function CALCULATE (handle,args...)
!DEC$ ATTRIBUTES DLLEXPORT::CALCULATE
useintrinsic :: iso_c_binding
implicit none
    integer(c_intptr_t), intent(in)  :: handle 
    type(type_udt),target :: data
    type(type_udt),pointer :: data_ptr
 
    pointer(handle,data)
     ! do calculation using data and args and return result
     ! ...
end function CALCULATE
 
0 Kudos
2 Replies
FortranFan
Honored Contributor II
276 Views

@Tobias, Loew:

Not sure what you mean by a better way, but in terms of "other" you can look into the enhanced interoperability with C features in standard Fortran in situations where the other programs you work with (using C++, etc.) do involve a companion C processor.  You may know of Intel's documentation of the C interop facilities: https://software.intel.com/en-us/node/678422 e.g., simulation example in this link.

0 Kudos
Tobias_Loew
Novice
276 Views

I was concerned about th LOC function which AFAIK is not standard. But I just found out about C_LOC and C_F_POINTER which give the guarantees I need (especially for non-interoperable types).

0 Kudos
Reply