У меня есть очень простая программа, которая очень смутила меня. Вызов 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.
Кто-нибудь может сказать мне, что идет не так?
Нет памяти было выделено для 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
Большое спасибо.
Моя проблема только что решена, цель этого примера состояла только в том, чтобы выделить память в подпрограмме 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
Я также добавил бы, что если вы хотите по какой-то причине пройти 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)
).