Мне нужно передать динамический массив из C ++ в Fortran. Я провел много исследований, чтобы собрать пример, который, по моему мнению, должен работать, но это не так. Программа должна создать массив в программе c ++, передать указатель этого массива в процедуру Fortran, преобразовать указатель C в указатель Fortran, а затем распечатать массив на стороне Fortran.
Моя основная программа на С ++:
using namespace std;
extern "C" {
void cinterface(int*,int*);
}
int main()
{
int carray[]={0,1,2,3,4};
int carray_siz=5;
cinterface(&carray_siz,carray);
return 0;
}
Моя рутина на Фортране:
module fortmod
use ISO_C_BINDING
implicit none
contains
subroutine cinterface(carray_siz,carray_ptr) bind(C)
implicit none
integer(c_int), intent(in) :: carray_siz
type(c_ptr), intent(in) :: carray_ptr
integer(c_int), pointer :: pfarray(:) => NULL()
call C_F_POINTER(carray_ptr,pfarray,[carray_siz])
print *, pfarray
end subroutine cinterface
end module fortmod
Я строю это как:
gfortran -c fortmod.f90
g++ main.cpp fortmod.o -lgfortran
Но когда я запускаю его, вместо печати значений массива он говорит:
Segmentation fault (core dumped)
Я новичок в идее указателей, поэтому я думаю, что не понимаю, как они работают правильно. Можете ли вы указать, почему я получаю эту ошибку памяти при запуске?
Конечно, вы хотите передать размер массива как int, не адрес размера:
extern "C" {
void cinterface(int,int*);
}
cinterface(carray_siz,carray);
Из руководства по gfortran:
Если указатель является фиктивным аргументом совместимой процедуры, он обычно должен быть
объявлено с использованием атрибута VALUE. void * соответствует TYPE (C_PTR), VALUE, в то время как TYPE (C_PTR) один соответствует void **.
Моя процедура на Фортране искала адрес указателя, а не адрес, на который указывает указатель. Поэтому, если я изменю сторону c ++ на это:
использование пространства имен std;
extern "C" {
void cinterface(int*,int**);
}
int main()
{
int carray[]={0,1,2,3,4};
int carray_siz=5;
cinterface(&carray_siz,&carray);
return 0;
}
перестроить и заново запустить, теперь я получаю:
0 1 2 3 4
как и ожидалось.