gpt4 book ai didi

c - Fortran 派生类型包含可从 C 访问的派生类型

转载 作者:太空宇宙 更新时间:2023-11-04 02:43:56 24 4
gpt4 key购买 nike

作为此 post 的扩展,我有派生类型,这些派生类型本身就是派生类型的成员。示例如下:

module simple
use iso_c_binding

TYPE SIMPLEF
INTEGER :: A
INTEGER, POINTER :: B, C(:)
END TYPE SIMPLEF

TYPE COMPLEXF
INTEGER :: X
TYPE (SIMPLEF) :: Y
END TYPE COMPLEXF
end module simple

如上文所述,目标是在 C 中具有相似的派生类型,并能够将值来回传递给 Fortran。解决方案可见here .但是这里它不仅仅是一个派生类型,它是一个派生类型,其成员本身就是派生类型。我是否需要为 COMPLEXF 创建 Y 的每个成员的子例程,即 SETY_A、QUERYY_A、SETY_B、QUERYY_BSIZE、SQUERYY_B 等?还是有更好的方法来解决这个问题?

最佳答案

可以使用相同的方法。什么是最好的取决于您认为什么是 C 客户端与 Fortran 对象交互的最佳方式。在编写太多代码之前,应该对此进行一些思考。

如前所述,y 组件的存在是 C 代码可能不需要关心的细节 - 而不是调用过程 sety_a 您可以只需将其命名为 set_a

如果在 COMPLEXF 类型的组件上有很多操作并且您想避免一定程度的间接访问,或者如果 COMPLEXF 有很多这样的组件> 相同类型,则可以使用与该组件对应的子对象的 C 地址作为不透明句柄。

为了示例,更改linked answer 中的GetHandleReleaseHandle 过程使用 COMPLEXF 类型作为顶级类型(即 - 用 COMPLEXF 替换该答案中 SIMPLEF 的所有外观)。然后,您可以按照以下行编写 QueryYHandle 过程或类似过程:

FUNCTION QueryYHandle(handle) RESULT(y_handle)
TYPE(C_PTR), INTENT(IN), VALUE :: handle
TYPE(C_PTR) :: y_handle
TYPE(COMPLEXF), POINTER :: p
!***
CALL C_F_POINTER(handle, p)
y_handle = C_LOC(p%y)
END FUNCTION QueryYHandle

现在您可以直接使用 SIMPLEF 子对象的句柄 - 使用与链接答案中完全相同的 Query*/Set* 过程。

在这种情况下,不需要编写过程来释放由 y_handle 指定的对象,因为与 y 组件关联的子对象的生命周期由具有该子对象的对象的生命周期 - 当调用 COMPLEXF super 对象的 ReleaseHandle 时,该子对象将消失。

请注意,如上所述,对于在语言之间传递错误类型的句柄,该方法没有任何保护措施(例如 - 如果 C 代码不小心调用了一个旨在与 COMPLEXF< 一起工作的过程 句柄实际上是一个 SIMPLEF 对象的句柄)。如果这是有问题的,那么可以添加保护,可能是通过将句柄类型与用作不透明句柄的对象中的 C 地址捆绑在一起,并在尝试将 Fortran 指针与 C 地址指定的对象相关联之前检查该句柄类型。

关于c - Fortran 派生类型包含可从 C 访问的派生类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29243820/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com