Arrays Fortran:指针数组的数组?
我正在使用一些Fortran代码(在本项目之前我从未使用过这些代码…),遇到了一个问题。我需要与另一个程序共享一些内存空间。为了让Fortran识别每个内存块,我使用以下代码:Arrays Fortran:指针数组的数组?,arrays,fortran,Arrays,Fortran,我正在使用一些Fortran代码(在本项目之前我从未使用过这些代码…),遇到了一个问题。我需要与另一个程序共享一些内存空间。为了让Fortran识别每个内存块,我使用以下代码: do 10 i = 0, 5 CALL C_F_POINTER(TRANSFER(memory_location + : VarNamesLoc_(i), : memory_location_cptr) , VarNames_(i), [3])
do 10 i = 0, 5
CALL C_F_POINTER(TRANSFER(memory_location +
: VarNamesLoc_(i),
: memory_location_cptr) , VarNames_(i), [3])
exit
10 continue
其中:
VarLoc(i)是表示内存位置的整数
VarNames(i)?指针数组的数组
我遇到的问题是创建指针数组的VarNames数组。我在谷歌上找到了一些示例代码,但我发现Fortran很难理解!!有人能告诉我如何设置指针数组吗?或者如果我处理问题的方法不正确,请指出另一种选择
作为参考,Fortran代码以自由形式编写,并使用intel编译器
谢谢你的帮助 好的,我假设冒号与连续行有关,忽略它们,然后尝试这样做:
do i = 0, 5
CALL C_F_POINTER(&
TRANSFER(memory_location + VarNamesLoc_(i), memory_location_cptr), &
VarNames_(i), [3] )
enddo
这样做的目的是:(传输)获取一个表示现有C指针的整数(我假设)内存位置
,在其上添加一个偏移量(VarNamesLoc\ui)
),并将其转换为一种类型的C\u ptr
。然后(C_F_指针)将其转换为Fortran形式的指针[3]
我认为在Fortran端执行C指针算法不是一个好主意,但是
因此,您希望VarNames\uu
是一个由5个指针组成的数组,指向3的数组。。有些事,你还没说。让我们说整数
让我们从一个简单的例子来看:假设我们在C中有一个一维整数数组,在Fortran中需要一个指向它们的指针。如果我们的C例程是这样(croutine.C
):
和这样的生成文件:
FC=gfortran
CC=gcc
CFLAGS=-std=c99 -g
FFLAGS=-g
main: driver.o croutine.o
$(FC) -o $@ $^
driver.o: driver.f90
$(FC) $(FFLAGS) -c $<
clean:
rm -rf main driver.o croutine.o
注意,在C中,我们分配了一个5个整数的数组;Fortran程序主要是定义C例程的接口,以便我们可以从Fortran调用它们,然后调用它们。c\u f\u指针执行c指针(cdata
)和Fortran指针(fdata
)之间的转换
如果我们想用Fortran做一些C指针算法,我们可以这样做:
但我真的不建议这样做;最好在Fortran中执行指针操作:
type(c_ptr) :: cdata
integer, pointer, dimension(:) :: fdata, newfdata
integer :: n = 5
call makearray(cdata, n);
call c_f_pointer(cdata, fdata, [n])
newfdata => fdata(3:n)
print *, 'newfdata = ', newfdata
call freearray(cdata, n)
type(c_ptr) :: cdata
integer :: n = 10
integer, parameter :: nptrs = 5
integer :: i, intsperptr
integer(kind=c_int) :: cint
integer(kind=int64) :: cdata_as_int
! our new "ptrelement" type which we can define arrays of
type ptrelement
integer, pointer, dimension(:) :: p
end type ptrelement
type(ptrelement) :: ptrs(nptrs)
call makearray(cdata, n);
cdata_as_int = TRANSFER(cdata, cdata_as_int)
intsperptr = n/nptrs
do i=1,nptrs
call c_f_pointer( &
TRANSFER(cdata_as_int + (i-1)*intsperptr*c_sizeof(cint), cdata),&
ptrs(i)%p, [intsperptr] )
enddo
do i=1,nptrs
print '(A,I2,A,99(I5,X))', 'ptrs(',i,')%p = ', ptrs(i)%p
enddo
call freearray(cdata, n)
更干净,不太可能导致wierd错误,而且更小
最后,让我们做一个指针数组。不可否认,这比在Fortran中更难,因为Fortran不容易让您定义指针数组;您必须创建一个已定义的类型(Fortran相当于C中的结构)。但这很容易。让我们按照我推荐的方式来做,在Fortran端做指针数学:
type(c_ptr) :: cdata
integer, pointer, dimension(:) :: fdata
integer :: n = 10
integer, parameter :: nptrs = 5
integer :: i, intsperptr, istart, iend
! our new "ptrelement" type which we can define arrays of
type ptrelement
integer, pointer, dimension(:) :: p
end type ptrelement
type(ptrelement) :: ptrs(nptrs)
call makearray(cdata, n);
call c_f_pointer(cdata, fdata, [n])
intsperptr = n/nptrs
do i=1,nptrs
istart = (i-1)*intsperptr+1
iend = istart + intsperptr-1
ptrs(i)%p => fdata(istart:iend)
enddo
do i=1,nptrs
print '(A,I2,A,99(I5,X))', 'ptrs(',i,')%p = ', ptrs(i)%p
enddo
call freearray(cdata, n)
在这里,我们创建了一个类型ptrellment
,它是一个一维指针数组,然后创建了这些指针数组。这为我们提供了指针数组,我们通过对fdata
进行切片来设置指针数组,它仍然是指向整个数据的指针
跑步给我们力量
$ ./main
ptrs( 1)%p = 0 1
ptrs( 2)%p = 2 3
ptrs( 3)%p = 4 5
ptrs( 4)%p = 6 7
ptrs( 5)%p = 8 9
或者,正如我不建议的那样,在Fortran中进行C型指针数学运算:
type(c_ptr) :: cdata
integer, pointer, dimension(:) :: fdata, newfdata
integer :: n = 5
call makearray(cdata, n);
call c_f_pointer(cdata, fdata, [n])
newfdata => fdata(3:n)
print *, 'newfdata = ', newfdata
call freearray(cdata, n)
type(c_ptr) :: cdata
integer :: n = 10
integer, parameter :: nptrs = 5
integer :: i, intsperptr
integer(kind=c_int) :: cint
integer(kind=int64) :: cdata_as_int
! our new "ptrelement" type which we can define arrays of
type ptrelement
integer, pointer, dimension(:) :: p
end type ptrelement
type(ptrelement) :: ptrs(nptrs)
call makearray(cdata, n);
cdata_as_int = TRANSFER(cdata, cdata_as_int)
intsperptr = n/nptrs
do i=1,nptrs
call c_f_pointer( &
TRANSFER(cdata_as_int + (i-1)*intsperptr*c_sizeof(cint), cdata),&
ptrs(i)%p, [intsperptr] )
enddo
do i=1,nptrs
print '(A,I2,A,99(I5,X))', 'ptrs(',i,')%p = ', ptrs(i)%p
enddo
call freearray(cdata, n)
哇,这是古代(fortran 77或更早版本)和现代(fortran 2003)构造的一个非常混乱的混合体。你能澄清要转移的论点吗?那些冒号在那里干什么?那个出口真的在那里吗?哇,谢谢你详细的回答,乔纳森!我今天会消化它,让你知道我的进展如何。您对冒号的假设是正确的,自由形式使用冒号而不是“&”(我正在处理的Fortran代码可以追溯到80年代初!)
$ ./main
ptrs( 1)%p = 0 1
ptrs( 2)%p = 2 3
ptrs( 3)%p = 4 5
ptrs( 4)%p = 6 7
ptrs( 5)%p = 8 9
type(c_ptr) :: cdata
integer :: n = 10
integer, parameter :: nptrs = 5
integer :: i, intsperptr
integer(kind=c_int) :: cint
integer(kind=int64) :: cdata_as_int
! our new "ptrelement" type which we can define arrays of
type ptrelement
integer, pointer, dimension(:) :: p
end type ptrelement
type(ptrelement) :: ptrs(nptrs)
call makearray(cdata, n);
cdata_as_int = TRANSFER(cdata, cdata_as_int)
intsperptr = n/nptrs
do i=1,nptrs
call c_f_pointer( &
TRANSFER(cdata_as_int + (i-1)*intsperptr*c_sizeof(cint), cdata),&
ptrs(i)%p, [intsperptr] )
enddo
do i=1,nptrs
print '(A,I2,A,99(I5,X))', 'ptrs(',i,')%p = ', ptrs(i)%p
enddo
call freearray(cdata, n)