Почему эта попытка передать указатель из C ++ в Fortran не работает?

Мне нужно передать динамический массив из 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)

Я новичок в идее указателей, поэтому я думаю, что не понимаю, как они работают правильно. Можете ли вы указать, почему я получаю эту ошибку памяти при запуске?

2

Решение

Конечно, вы хотите передать размер массива как int, не адрес размера:

extern "C" {
void cinterface(int,int*);
}

cinterface(carray_siz,carray);
4

Другие решения

Из руководства по 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

как и ожидалось.

1

По вопросам рекламы [email protected]