Fortran:指针数组的数组?
我正在使用一些 Fortran 代码(在这个项目之前我从未使用过......)并且遇到了问题。我需要与另一个程序共享一些内存空间。为了让 Fortran 识别每个内存块,我使用以下代码:
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 代码以自由形式编写并使用英特尔编译器
感谢您的帮助!
I'm working with some Fortran code (which I'd never used until this project...) and have come up against a problem. I need to share some memory space with another program. To get Fortran to recognise each memory chunk I use the following code:
do 10 i = 0, 5
CALL C_F_POINTER(TRANSFER(memory_location +
: VarNamesLoc_(i),
: memory_location_cptr) , VarNames_(i), [3])
exit
10 continue
Where:
VarLoc(i) is an integer representing the memory location
VarNames(i) ?Array of pointer arrays?
The problem I'm having is creating the VarNames array of pointer arrays. I've found some sample code from my googling but I find Fortran quite difficult to understand!! Can anyone show me how to set up an array of pointer arrays? Or point out an alternative if I'm approaching the problem incorrectly?
For reference the Fortran code is written in free form and uses an intel compiler
Thanks for any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,所以我假设冒号与连续行有关并忽略它们,并且您正在尝试执行此操作:
它所做的是:(传输)采用表示现有 C 指针的整数(我假设)
memory_location
,为其添加偏移量 (VarNamesLoc_(i)
),并将其转换为c_ptr
类型。然后(C_F_POINTER)将其转换为形状 [3] 的 Fortran 指针。我不认为在 Fortran 端进行 C 指针算术是一个好主意,但是。
所以你希望
VarNames_
成为一个由 5 个指针组成的数组,指向由 3.. 某些东西组成的数组,你没有说。比如说整数。让我们从简单的情况来看:假设我们在 C 中有一个一维整数数组,并且想要在 Fortran 中有一个指向它们的指针。如果我们的 C 例程是这样的 (
crooutine.c
):我们的 Fortran 驱动程序可能如下所示 (driver.f90):
和一个像这样的 Makefile:
构建并运行它,我们会得到预期的答案:
请注意,在 C 中我们分配了一个 5 个整数的数组; Fortran 程序主要定义 C 例程的接口,因此我们可以从 Fortran 调用它们,然后调用它们。
c_f_pointer
执行 c 指针 (cdata
) 和 Fortran 指针 (fdata
) 之间的转换。如果我们想在 Fortran 中进行一些 C 指针算术,我们可以这样做:
但我真的不会推荐这样做;更好地在 Fortran 中进行指针操作:
更干净,不太可能导致奇怪的错误,而且也更小!
好吧,最后,让我们做一个指针数组。诚然,这比 Fortran 中应该更难,因为 Fortran 不容易让您定义指针数组;您必须创建一个已定义的类型(Fortran 相当于 C 中的结构)。但这很容易。让我们按照我推荐的方式做事,在 Fortran 端进行指针数学运算:
这里我们创建了一个 ptrelelment 类型,它是一个一维指针数组,然后创建了一个由这些指针组成的数组。这给了我们指针数组,我们通过获取
fdata
切片来设置它,它仍然是指向整个数据的指针。运算:
或者,正如我不建议的那样,在 Fortran 中进行 C 风格的指针数学
Ok, so I'm going to assume the colons have something to do with continuation lines and ignore them, and that you're trying to do this:
What this is doing is: (the TRANSFER) taking an integer representing existing C pointer (I assume)
memory_location
, add an offset to that (VarNamesLoc_(i)
), and turn it into a type ofc_ptr
. And then (the C_F_POINTER) converting that to a Fortran pointer of shape [3].I don't think doing the C-pointers arithmetic on the Fortran side is a great idea, but.
So you want
VarNames_
to be an array of 5 pointers to arrays of 3.. somethings, you haven't said. Let's say integers.Let's take it from the simple case: let's just say we had a 1 dimensional array of ints in C, and wanted a pointer to them in Fortran. If our C routine was this (
croutine.c
):our Fortran driver might look like this (driver.f90):
and a Makefile like this:
and building it and running it we get the expected answer:
Note that in C we allocated an array of 5 ints; the Fortran program is mostly defining the interface to the C routines so we can call them from Fortran, then calling them. The
c_f_pointer
does the translation between the c pointer (cdata
) and the Fortran pointer (fdata
).If we wanted to do some C-pointer arithmetic in Fortran, we could do this:
But I really wouldn't recommend this; better to do the pointer manipulations in Fortran:
Cleaner, less likely to cause wierd errors, and smaller, too!
Ok, so finally, let's do an array of pointers. This, admittedly, is harder than it should be in Fortran because Fortran doesn't easily let you define arrays of pointers; you have to create a defined type (the Fortran equivalent of a struct in C). But it's easy enough. Let's do things the way I recommend, doing the pointer math on the Fortran side:
Here we've created a type
ptrelelment
which is a 1-d pointer array, then created an array of those. That gives us our array of pointers, which we set by taking slices offdata
, which is still the pointer to the whole data.running gives us
Or, as I do not suggest, doing the C-style pointer math in Fortran: