使用iso_c_binding,发送c_ptr到C, malloc,, set value



问题:如何让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

注意:程序将泄漏malloced字节,除非你添加一个free

摘自PierU的评论:

Fortran通过地址传递参数:当你调用roll_dice(test_ptr)时,传递的不是test_ptr的内容,而是它的地址。也就是说,用C表示,一个指针指向另一个指针。此外,为了代码的正确性,test_p在你的接口中应该是intent(inout)

相关内容

  • 没有找到相关文章

最新更新