I have a fortran module, which is part of a c++ program. This module has a global variable, which is a 3d array, and which I would like to have pointed to a 3d Tensor I am defining in c++:
test.cpp
:
#include <Eigen/Dense>
#include <unsupported/Eigen/CXX11/Tensor>
extern "C" {
void f_link_global_variable(double* data, int* dims, int* strides);
}
int main(){
Eigen::Tensor<double, 3> tensor(1,2,3);
tensor.setZero();
tensor(0,0,0) = 1;
std::array<int, 3> dims = {tensor.dimension(2), tensor.dimension(1), tensor.dimension(0)};
int n_dims = 3;
std::cout << "tensor before passing: " << tensor << std::endl; // prints 1 0 0 0 0 0
f_link_global_variable(tensor.data(), dims.data(), &n_dims);
std::cout << "tensor after passing: " << tensor << std::endl;
}
stub_fortran_interface.f90
:
module fortran_testmodule
use iso_c_binding
implicit none
double precision, pointer :: my_global_ndarray(:,:,:)
contains
subroutine link_global_variable(c_pointer, dims, n_dims) bind(C, name="f_link_global_variable")
type(c_ptr), intent(in) :: c_pointer
integer(c_int), intent(in) :: dims(*)
integer(c_int), intent(in) :: n_dims
integer, allocatable :: shape_(:)
integer :: i
allocate(shape_(n_dims))
do i = 1, n_dims
shape_(i) = dims(i)
end do
call c_f_pointer(c_pointer, my_global_ndarray, shape_)
! generates segfault:
print *, "array in fortran:", my_global_ndarray
my_global_ndarray(1,1,2) = 3
end subroutine link_global_variable
end module fortran_testmodule
I am linking these files with
enable_language(Fortran)
add_library(stub_fortran_interface SHARED stub_fortran_interface.f90)
target_compile_options(stub_fortran_interface PUBLIC "-fvisibility=default")
add_executable(test test.cpp)
target_link_libraries(test_cpp_fortran_interface
PUBLIC
stub_fortran_interface)
When I try to print the newly allocated public array in fortran, I get a segmentation fault. Why am I not able to access the values I am defining in my c++ code? Note that the c++ Eigen
library uses by default the same col-major format as Fortran, so the issue is not related to the alignment of the array values.
Since this code uses both fortran and c++, I am unable to provide working code in a compiler explorer, so I would be grateful if you could let me know if there is anything that is not working properly.