【问题标题】:Fortran derived types containing derived types to be accessible from CFortran 派生类型包含可从 C 访问的派生类型
【发布时间】:2015-03-24 22:09:38
【问题描述】:

作为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。然而这里它不仅仅是一个派生类型,它是一个派生类型,其成员本身就是派生类型。我是否需要为 Y 的每个成员(即 SETY_A、QUERYY_A、SETY_B、QUERYY_BSIZE、SQUERYY_B 等)创建 COMPLEXF 子例程?还是有更好的方法来解决这个问题?

【问题讨论】:

    标签: c pointers fortran fortran-iso-c-binding derived-types


    【解决方案1】:

    可以使用相同的方法。什么是最好的取决于您认为 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 超级对象的 ReleaseHandle 时,该子对象将消失。

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

    【讨论】:

    • 感谢您的详细解答。所以在 Fortran 中,我仍然可以更改 COMPLEXF 变量的 y SIMPLEF 分量,然后 C 将使用 C_LOC 排列取回更新的分量。我猜如果我愿意的话,我仍然可以在这个阶段访问 C 端中 y 的子组件,或者我可以将 y(已经用 C_LOC 取回)等同于另一个具有 C 中更新值的 SIMPLEF 类型变量。
    猜你喜欢
    • 2015-04-17
    • 2014-10-18
    • 2012-10-23
    • 2019-03-02
    • 2018-07-14
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    相关资源
    最近更新 更多