test.cpp
#include < stdlib.h >
// fortran can only call C routines
extern "C" {
// we need the address of the fortran pointer thus a pointer of a pointer.
void myC_func(int **arr) {
// we cannot use new() here because fortran deallocate() use free() instead of delete[]
*arr = (int*) malloc(12*sizeof(int));
for(int i=0; i < 12; i++) {
(*arr)[i] = i;
}
}
}
test.F90
! https://gcc.gnu.org/onlinedocs/gcc-4.6.2/gfortran/Working-with-Pointers.html
program main
use iso_c_binding
implicit none
interface
subroutine my_routine(arr) bind(c,name='myC_func')
import :: c_ptr
! If a pointer is a dummy-argument of an interoperable procedure,
! it usually has to be declared using the VALUE attribute.
! void* matches TYPE(C_PTR), VALUE, while TYPE(C_PTR) alone matches void**.
type(c_ptr), intent(out) :: arr
end subroutine
end interface
type(c_ptr) :: cptr
integer,pointer :: fptr(:)
! allocate and fill cptr
call my_routine(cptr)
! convert it to fortran pointer
call c_f_pointer(cptr, fptr, [12])
if(associated(fptr)) write(*,*) "associated"
write(*,*) fptr
deallocate(fptr)
end program main
g++ -Wall -Wextra -c test.cpp gfortran -Wall -Wextra -fcheck=all test.F90 test.o valgrind ./a.out ==5256== Memcheck, a memory error detector ==5256== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==5256== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info ==5256== Command: ./a.out ==5256== associated 0 1 2 3 4 5 6 7 8 9 10 11 ==5256== ==5256== HEAP SUMMARY: ==5256== in use at exit: 0 bytes in 0 blocks ==5256== total heap usage: 22 allocs, 22 frees, 11,874 bytes allocated ==5256== ==5256== All heap blocks were freed -- no leaks are possible ==5256== ==5256== For counts of detected and suppressed errors, rerun with: -v ==5256== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)