c_f_pointer не работает

У меня есть очень простая программа, которая очень смутила меня. Вызов c_f_pointer не работает, по-видимому, я делаю много ошибок!

program test
use iso_c_binding
implicit none
interface
subroutine call_fc(size,status) bind(C,name='call_fc_')
import
integer(c_int) :: size
type(c_ptr) :: status
end subroutine
end interface
integer(c_int) :: size=8,i
integer(c_int),pointer  :: stat(:)
type(C_ptr) :: statptr
call call_fc(size, statptr)
call c_f_pointer(statptr,stat,(/size/))
print *, 'stat is : ',stat
end program test

и подпрограмма с ++

extern "C" {
void call_fc_(int *size, int *status)
{
int i;
for(i=0; i<*size;i++) {
status[i] = i+10;
printf("%d th value : %d \n", i, status[i]);
}
}
}

когда я компилирую и запускаю код, он выдаст следующую ошибку

0 th value : 10
1 th value : 11
2 th value : 12
3 th value : 13
4 th value : 14
5 th value : 15
6 th value : 16
7 th value : 17

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Кто-нибудь может сказать мне, что идет не так?

0

Решение

Нет памяти было выделено для stat/status,

Если целью является передача целочисленного массива в подпрограмму C ++, тогда c_f_pointer не требуется:

program test
use iso_c_binding

implicit none

interface
subroutine call_fc(size,status) bind(C,name='call_fc_')
import c_int
integer(c_int) :: size
integer(c_int) :: status(size)
end subroutine call_fc
end interface

integer(c_int), parameter :: size=8
integer(c_int) stat(size)

call call_fc(size, stat)

print *, 'stat is : ',stat
end program test
1

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

Большое спасибо.
Моя проблема только что решена, цель этого примера состояла только в том, чтобы выделить память в подпрограмме C или C ++ и передать выделенную память в FORTRAN, в противном случае, я также знаю, что в этом нет необходимости.

program test
use iso_c_binding
implicit none
interface
function call_fc(size) bind(C,name='call_fc')
import :: c_int, c_ptr
integer(c_int) :: size
type(c_ptr) :: call_fc
end function
end interface
integer(c_int) :: size=8,i
integer(c_int),pointer  :: stat(:)
call c_f_pointer(call_fc(size),stat,(/size/))
print *, 'stat is : ',stat
end program test

и подпрограмма с ++

extern "C" {
void * call_fc(int *size)
{
int i;
int * status = new int [*size];
for(i=0; i<*size;i++) {
status[i] = i+10;
printf("%d th value : %d \n", i, status[i]);
}
return status;
}
}

когда я компилирую и запускаю код, он выдаст правильный ответ

0 th value : 10
1 th value : 11
2 th value : 12
3 th value : 13
4 th value : 14
5 th value : 15
6 th value : 16
7 th value : 17

stat is : 10   11    12   13   14   15   16   17
1

Я также добавил бы, что если вы хотите по какой-то причине пройти type(c_ptr) (например, чтобы иметь возможность пройти null), вы должны использовать value атрибут, если аргумент на стороне C — это просто указатель, переданный по значению, как в вашем примере.

interface
subroutine call_fc(size,status) bind(C,name='call_fc_')
import
integer(c_int) :: size
type(c_ptr), value :: status
end subroutine
end interface

даже после этого ваша конкретная процедура C требует, чтобы переданный указатель указывал на какой-то допустимый фрагмент памяти (размером size*sizeof(int)).

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