我正在修改一些预先存在的代码以使用Fortran iso_c_binding标准。在Fortran端我定义了一个整数,这个整数通过C malloc为数组存储空间,我有一个类似的变量(但是一个实数)在Fortran端被设置为许多值。实数被用来设置值,在C中曾经是整数。我如何修改下面的程序以使用iso_c_binding实现这一点?Fortran和/或C代码必须更改吗?
文件main.f90:
program main
use the_interface
use iso_c_binding, only : c_int,c_ptr,c_loc
implicit none
type(myint), pointer :: intvar
type(c_ptr), pointer :: value_ptr
type(real), allocatable, target :: value(:)
type(c_ptr) :: myint_ptr
integer ans,i
allocate(value(10),value_ptr)
value_ptr = c_loc(value)
do i = 1,10
value(i) = real((i-1) * 3 + (i-1),4)
end do
ans = get_storage(myint_ptr)
ans = set_source(myint_ptr,value_ptr)
ans = print_source(myint_ptr)
end program main
文件测试c:
#include <stdio.h>
#include <stdlib.h>
typedef int int_type;
struct myint {
int value;
};
#define NUM 10
int get_storage_ (int_type **dest)
{
*dest = (int_type *)malloc(NUM * sizeof(int_type));
if (!*dest) {
return -1;
}
return 0;
}
int set_source_ (struct myint **dest, struct myint *source)
{
int i;
int counter = 0;
for (i = 0;i < NUM;i++)
{
/* (*dest + i)->value = i * 3 + i; */
(*dest + i)->value = (source + i)->value;
if (!(++counter % 5))
{
printf ("\n");
counter = 0;
}
}
return 0;
}
int print_source_ (struct myint **dest)
{
int i;
int counter = 0;
int errors = 0;
for (i = 0;i < NUM;i++)
{
if (((*dest + i)->value) != (i * 3 + i))
{
printf ("Error at %d %d != %d ",i, ((*dest + i)->value),(i * 3 + i));
errors ++;
}
else
{
printf ("Value at %d = %d ",i,(*dest + i)->value);
}
counter++;
if (!(counter % 5))
{
printf ("\n");
counter = 0;
}
}
printf ("\n%d values weren't set correctly!\n",errors);
printf ("%d values were set correctly!\n\n",NUM - errors);
return 0;
}
将_接口. f90归档:
module the_interface
use iso_c_binding, only: c_int,c_ptr,c_float
type, bind(c) :: myint
integer(c_int) :: int_tmp
end type
type, bind(c) :: myfloat
real(c_float) :: float_tmp
end type
function get_storage(address)bind(c,name="get_storage_")
import :: c_int, c_ptr, myint
implicit none
type(c_ptr), intent(inout) :: address
integer(c_int) :: get_storage
end function
function set_source(address, value)bind(c,name="set_source_")
import :: c_int, c_ptr, myint
implicit none
type(c_ptr), intent(inout) :: address
type(c_ptr), intent(inout) :: value
integer(c_int) :: set_source
end function
function print_source(address)bind(c,name="print_source_")
import :: c_int, c_ptr, myint
implicit none
type(c_ptr), intent(inout) :: address
integer(c_int) :: print_source
end function
end interface
end module the_interface
编译和运行:
gcc -g -c test.c -o test.o
gfortran -g -c the_interface.f90 -o the_interface.o
gfortran -g -c main.f90 -o main.o
gfortran -g main.o test.o -o main.exe -lgfortran
./main.exe
输出:
0 38195424处出错!= 0 1 38195424处出错!= 4 2 38195424处出错!= 8 3 38195424处出错!= 12 4 38195424处出错!= 16 5 38195424处出错!= 20 6 38195424处出错!= 24错误位置7 38195424!= 28错误位置8 38195424!= 32错误位置9 38195424!= 36
10个值设置不正确! 0个值设置正确!
(1)我尝试修改test. c文件中set_source_routine的以下行:
(*dest + i)->value = (source + i)->value;
我希望输出为:
0 = 0处的值1 = 4处的值2 = 8处的值3 = 12处的值4 = 16处的值5 = 20处的值6 = 24处的值7 = 28处的值8 = 32处的值9 = 36处的值
0个值设置不正确! 10个值设置正确!
(2)我试着从set_source_function的"struct myint * source"形参定义中删除"struct",但无法编译。
(3)在set_source_中使用"source [i]. value"而不是"(source + i)-〉value"也没有达到我想要的效果,它给出了同样错误的输出。
(4a)如果我把set_source_function形参的定义改为"struct myint**source"而不是"struct myint * source",我仍然会得到9个错误的值,第一个值是0。(4b)如果在 * error * printf中我也把第二个printf格式说明符从" % d"改为" % f",那么数组元素打印出来时都是0。
1条答案
按热度按时间xqk2d5yq1#
这里有一个解决方案,您可以改进iso_c_binding接口代码吗?