I know this has been asked in various forms before but I can't find anything matching my exact case.
kernel.cpp:
#include <iostream>
extern "C" void ckernel(int i, int* ptr) {
//std::cout << i << std::endl;
//std::cout << ptr[i] << std::endl;
std::cout << ptr[0] << std::endl;
std::cout << ptr[1] << std::endl;
std::cout << ptr[2] << std::endl;
//ptr[i] = ptr[i] + 5;
}
main.f90
module util
use iso_c_binding
interface
subroutine ckernel(i, x) bind(c)
use iso_c_binding
implicit none
integer(c_int), value, intent(in) :: i
integer(c_int), allocatable, target :: x(:)
end subroutine
end interface
end module
program test
use iso_c_binding
use util
integer(c_int), allocatable, target :: x(:)
allocate(x(3))
x(1) = 1
x(2) = 2
x(3) = 3
call ckernel(2, x)
end program
Makefile (There's a reason why I am linking with c++ compiler, I don't think this is an issue)
all: driver
main.o : main.f90
ifort -c main.f90
CLFAGS=-g -O2
kernel.o: kernel.cpp
icpc ${CFLAGS} -c kernel.cpp
driver: main.o kernel.o
icpc ${CFLAGS} -o driver main.o kernel.o -lifcore -lifcoremt -lifcore -lifport -qopenmp /soft/compilers/intel-2019/compilers_and_libraries_2019.4.243/linux/compiler/lib/intel64_lin/for_main.o
clean:
rm -f main.o kernel.o driver
The pointer does not get passed correctly to C++
./driver
18763904
0
4
The problem must be the way I define my interface because this works (changing the name of ckernel to ckernel_):
! use iso_c_binding
! interface
! subroutine ckernel(i, x) bind(c)
! use iso_c_binding
! implicit none
! integer(c_int), value, intent(in) :: i
! integer(c_int), allocatable, target :: x(:)
! end subroutine
! end interface
!end module
program test
use iso_c_binding
! use util
integer(c_int), allocatable, target :: x(:)
allocate(x(3))
x(1) = 1
x(2) = 2
x(3) = 3
call ckernel(2, x)
end program
./driver
1
2
3