This statement "I cannot use the ISO C bindings as that is only for Fortran 2003 and up." is odd; any current compiler that supports F90 also supports most or all of F2003.
As Eric Urban points out, it's easiest just to do the array allocation within fortran of course (where you actually can use array slicing or broadcasting to do the filling easier). But assuming there is some C routine you need to call that takes this form, just use the ISO_C_BINDING module for portable interfacing between C and fortran:
program test_real
use, intrinsic :: iso_c_binding
real(kind=c_float), pointer :: realpt(:)
type(c_ptr) :: ptr
integer :: nbr
integer :: i
real :: a=1.0
real :: b=2.0
real :: c=3.0
interface
function getpointer(a, b, c) result(ptr) bind(C,name="getpointer")
use, intrinsic :: iso_c_binding
implicit none
type(c_ptr) :: ptr
real(kind=c_float) :: a, b, c
end function getpointer
end interface
nbr = 9
ptr = getpointer(a, b, c)
call c_f_pointer(ptr, realpt, [nbr])
print *,"return: ",realpt
end
Compiling and running gives
$ gcc -c fooc.c
$ gfortran -c foo.f90
$ gfortran -o foo foo.o fooc.o
$ ./foo
return: 1.0000000 1.0000000 1.0000000 2.0000000 2.0000000 2.0000000 3.0000000 3.0000000 3.0000000
If you try to do this in some way to get around 7+ year old compilers limitations, there's a bunch of brittle non-portable ways to do it, but it's really not worth the heartache.
Update: If you can't touch (or even recompile) some of the older fortran, then you can at least make an F2003 wrapper for the C program and have the older fortran link to it:
foowrapper.f90:
module wrapper
contains
subroutine wrapgetpointer(outarr)
use, intrinsic :: iso_c_binding
implicit none
real, intent(out), dimension(:) :: outarr
real(kind=c_float), pointer :: realpt(:)
type(c_ptr) :: ptr
integer :: nbr = 9
real(kind=c_float) :: a, b, c
interface
function getpointer(a, b, c) result(ptr) bind(C,name="getpointer")
use, intrinsic :: iso_c_binding
implicit none
type(c_ptr) :: ptr
real(kind=c_float) :: a, b, c
end function getpointer
end interface
a = 1.
b = 2.
c = 3.
ptr = getpointer(a, b, c)
call c_f_pointer(ptr, realpt, [nbr])
outarr(1:nbr) = realpt
end subroutine wrapgetpointer
end module wrapper
foo.f90:
program test_real
use wrapper
real, dimension(9) :: array
call wrapgetpointer(array)
print *,"return: ",array
end
Compiling and running:
$ gfortran -c foowrapper.f90
$ gfortran -c foo.f90
$ gcc -c fooc.c
$ gfortran -o foo foo.o foowrapper.o fooc.o
$ ./foo
return: 1.0000000 1.0000000 1.0000000 2.0000000 2.0000000 2.0000000 3.0000000 3.0000000 3.0000000