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

Fortran to C and Back, the saga continues

rforehan
Beginner
299 Views

My poor old brain has turned to jello trying to set up the interface for the following C++ routine:

extern "C" float* getFrequencies(int &n);

The function returns a pointer to anarray of floats and sets n to the number of values in the array.

I placed the function interface into a module as follows:

MODULEMyModule
USE ISO_C_BINDING
IMPLICIT NONE

FUNCTION getFrequency(n)
interface
function getFrequencies(n)
use ISO_C_BINDING
real(C_FLOAT), dimension(:), pointer :: getFrequencies
!DEC$ ATTRIBUTES C,REFERENCE,DECORATE, &
ALIAS:"getFrequencies" :: getFrequencies
integer(C_INT), intent(INOUT) :: n
!DEC$ ATTRIBUTES REFERENCE :: n
end function
end interface

real, dimension(:), pointer :: getFrequency
integer n
getFrequency => getFrequencies(n)
END FUNCTION

END MODULE

Then I attempted to use the function as follows:
real, dimension(:), pointer :: frequencies
integer numPts

frequencies => getFrequency(numPts);

I was guessing that I had to turn the float pointer into a dimensioned array in Fortran, but I'm missing some concept in understanding how to go about doing it.

Thanks for any help in retraining an old dog,

Dick

0 Kudos
3 Replies
Steven_L_Intel1
Employee
299 Views
The C function doesn't return an array, it returns a pointer, so that's how you'll have to declare it. Try this:

MODULE MyModule
USE ISO_C_BINDING
IMPLICIT NONE

contains

FUNCTION getFrequency(n)
interface
function getFrequencies(n) bind(C,name="_getFrequencies")
import
type(C_PTR) :: getFrequencies
integer(C_INT), intent(INOUT) :: n
end function
end interface

real, dimension(:), pointer :: getFrequency
integer n

call C_F_PTR(getFrequencies(n), getFrequency, )

END FUNCTION

END MODULE

You'll have to remove the leading underscore from the name= when we fix the compiler bug in this regard.
0 Kudos
rforehan
Beginner
299 Views

Steve,

I'm using version 10.0.025 of the compiler. Has the bug been fixed in it? I had to remove that leading "_"after name= to avoid link error Also add to change to C_F_POINTER.

Aside from that, it worked great.

I'm still trying to fully understand the POINTER attribute. It seems more like an access type in Ada as opposed to a C pointer. Does the normal assignment operator "=" automatically dereference the variable, i.e.,ptr A = ptr B sets the value pointed to by A to the value pointed to by B instead of setting A to point to the same address as B, whereasthe pointer assignmentoperator "=>"(ptr A => ptr B) sets ptr A to point to the same address as ptr B? Man, that looks like typo hell just waiting to grab you.

Thanks again for your help,

Dick

0 Kudos
Steven_L_Intel1
Employee
299 Views
Sorry about the C_F_PTR - that was my error.

Actually, the bug I mentioned was introduced in 10.0.026 or thereabouts and is not fixed yet. It was due to a misunderstanding.

POINTER is not like C pointers. Automatic dereferencing does occur depending on the context. You have the distinction correct.
0 Kudos
Reply