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

Dynamic allocation

IDZ_A_Intel
Employee
918 Views

I have a fortran routine, which is calling a C++ routine. The C++ routine will return an array of structures and the number of elements in the array.

My issue is that I would like to dynamically allocate memory for the array, however I do not know the size prior to calling the C++ routine.

Any suggestions?

0 Kudos
4 Replies
qolin
Novice
918 Views

I guess your C routine will, in fact, allocate memory for the array using MALLOC or whatever way is usual for C (I'm not a C phreak). Then it returns with its argument set to the address of the array, the usual C-style pointer. So your task is to use that pointer and make something on the Fortran side understand it. To me that sounds like it needs a CRAY-pointer, i.e. a pointer created with a POINTER statement (not a pointer attribute).

I won't go into any further deatils because, to be honest, I'm on rather shaky ground here, and your post doesn't really give sufficient information (notice the first 2 words above). However if you look up cray pointers in IVF help you should find it useful.

Perhaps someone else has a firmer opinion?

Qolin

0 Kudos
TimP
Honored Contributor III
918 Views
Cray pointer was the most usual pre-f2003 method for using dynamic memory allocation performed by C. Such usage was standardized in f2003 with iso_c_binding, c_f_pointer.
0 Kudos
Paul_Curtis
Valued Contributor I
918 Views

This is very typical of Win32 programming, where the canonical arguments passed from the opsys to user proc functions frequently refer to Win32 data structures. Here is a typical proc function, in F90, which (further on in the code) processes messages with extra information in an nmhdr structure, passed as an address via lParam:

[bash]INTEGER FUNCTION ConflictProc (hwnd, msg, wParam, lParam) RESULT (res)
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS : '_ConflictProc@16' :: ConflictProc
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'ConflictProc' :: ConflictProc
!DEC$ ENDIF
    IMPLICIT NONE
    INTEGER(HANDLE),  INTENT(IN)   :: hwnd
    INTEGER(UINT),    INTENT(IN)   :: msg
    INTEGER(fWPARAM), INTENT(IN)   :: wParam
    INTEGER(fLPARAM), INTENT(IN)   :: lParam

    	TYPE(T_NMHDR)				   :: nmhdr
    POINTER(lParam, nmhdr)
[/bash]

and then the F90 part of the code simply uses nmhdr%component as needed.

0 Kudos
IDZ_A_Intel
Employee
918 Views

Portable, F2003 std compliant example that uses the approach alluded to by tim18.

C++ determines the size of the array, allocates the memory, returns a C_PTR and the size of the array (via a pass-by-reference parameters/arguments) back to Fortran. Fortran associates the returned c-ptr with a standard fortran POINTER, then does some useful work. When finished, it calls back into C++ so that C++ can cleanup (this time passing the C_PTR by value).

CountrySide.f90

SeaSide.cpp

0 Kudos
Reply