1

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
SayAz
  • 751
  • 1
  • 9
  • 16

0 Answers0