问题:如何让28回Fortran?
main.f90:
program test
use play_dice_game
use iso_c_binding, only : c_ptr, c_f_pointer, c_null_ptr
type(c_ptr) :: test_ptr
integer, pointer :: ftest_ptr
integer result
test_ptr = c_null_ptr
result = roll_dice(test_ptr)
call c_f_pointer(test_ptr, ftest_ptr)
write(*,*) 'C test pointer is ',test_ptr
write(*,*) 'Fortran test pointer is ',ftest_ptr
end program test
play_dice_game.f90:
module play_dice_game
use, intrinsic :: iso_c_binding, only: c_int, c_ptr
interface
function roll_dice(test_p) bind(c, name="roll_dice_")
import :: c_int, c_ptr
implicit none
type(c_ptr), intent(out) :: test_p
integer(c_int) :: roll_dice
end function
end interface
end module play_dice_game
test.c:
#include <stdio.h>
#include <stdlib.h>
int roll_dice_(int *test) {
if (!*test)
{
printf ("Creating storage for testn");
test = malloc(sizeof(int));
*test = 28;
printf ("variable test is set to %dnn",*test);
}
else
{
printf ("test is not nulln");
}
return 0;
}
编译和运行程序:
gcc -g -c test.c -o test.o
gfortran -g -c play_dice_game.f90 -o play_dice_game.o
gfortran -g -c main.f90 -o main.o
gfortran -g main.o test.o -o main.exe -lgfortran
./main.exe
输出:
为测试创建存储变量测试设置为28
C测试指针为0Fortran测试指针为0
我尝试使用c_f_pointer没有成功。但是,如果我在C文件中定义一个带int的结构体并在Fortran文件中引用它,我可以得到"28"在Fortran。我想要一些简单的。
在C:
struct myint {
int int_tmp;
};
int roll_dice_(struct myint **test)
...
*test = malloc(sizeof(**test));
...
(*test)->int_tmp = 28;
在Fortran:
type(myint), pointer :: intvar
call c_f_pointer(myint_ptr, intvar)
write(*,*) 'my int = ', intvar%int_tmp
我不知道fortran是如何工作的,但是你的C函数有一个问题。分配内存,然后释放指向该内存的指针。
我建议您在roll_dice_
中使用int **
,以便能够返回指向已分配内存的指针。例子:
#include <stdio.h>
#include <stdlib.h>
int roll_dice_(int **test) {
if(!test) {
puts("test is null");
return 0; // 0 for fail
}
if(!*test) {
printf("Creating storage for testn");
*test = malloc(sizeof **test);
} else {
printf("*test is not nulln");
}
**test = 28;
printf("variable test is set to %dnn", **test);
return 1; // 1 for success
}
可能的输出:
Creating storage for test
variable test is set to 28
C test pointer is 11640096
Fortran test pointer is 28
注意:程序将泄漏malloc
ed字节,除非你添加一个free
。
摘自PierU的评论:
Fortran通过地址传递参数:当你调用
roll_dice(test_ptr)
时,传递的不是test_ptr
的内容,而是它的地址。也就是说,用C表示,一个指针指向另一个指针。此外,为了代码的正确性,test_p
在你的接口中应该是intent(inout)
。