包含派生类型Fortran派生类型是从C访问 [英] Fortran derived types containing derived types to be accessible from C

查看:168
本文介绍了包含派生类型Fortran派生类型是从C访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为扩展到本<一href=\"http://stackoverflow.com/questions/28543180/fortran-derived-types-containing-pointers-to-be-accessible-from-c\"标题=LINK>帖子,我已经得出具有作为成员派生类型本身的类型。下面的例子:

As an extension to this post, I have derived types which have as members derived types themselves. Example below:

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语言。该溶液可以看出 href=\"http://stackoverflow.com/a/28551786/4572020\">。不过在这里它不只是一个派生类型,它是一个派生类型与它属于派生类型本身的成员。我需要创建COMPLEXF,Y的每个成员,即SETY_A,QUERYY_A,SETY_B,QUERYY_BSIZE,SQUERYY_B等子程序?还是有更好的方式来处理这个?

The aim is, as in the post above, to have similar derived types in C and to be able to pass values back and forth to Fortran. The solution can be seen here. However here it's not just a derived type, it is a derived type with a member which is a derived type itself. Would I need to create for COMPLEXF, subroutines for each member of Y, i.e. SETY_A, QUERYY_A, SETY_B, QUERYY_BSIZE, SQUERYY_B etc.? Or is there a better way to approach this?

推荐答案

可以使用同样的方法。什么是最好的取决于你认为是你的C客户端与您的Fortran对象交互的最佳方式。你写太多code之前的一些想法应该投入这一点。

The same approach can be used. What's best depends on what you think is the best way for your C clients to interact with your Fortran objects. Some thought should be put into this before you write too much code.

由于presented,在 y的存在组件是一个细节,在C code可能并不需要关心 - 而不是调用程序 sety_a 你可以只将其命名为 set_a

As presented, the existence of the y component is a detail that the C code probably doesn't need to care about - rather than calling the procedure sety_a you could just name it set_a.

如果有将要的 COMPLEXF 键入你想要避免间接的级别,或者有许多这样的组件<组件上的许多操作code> COMPLEXF ,那么你可以使用对应于组件作为一个不透明的手柄子对象的C类地址。

If there are going to be many operations on the component of the COMPLEXF type and you want to avoid a level of indirection, or if there are many such components of COMPLEXF of the same type, then you can use the C address of the subobject that corresponds to that component as an opaque handle.

例如起见,改变的<一个在 GetHandle ReleaseHandle 程序href=\"http://stackoverflow.com/questions/28543180/fortran-derived-types-containing-pointers-to-be-accessible-from-c/28551786#28551786\">linked回答一起工作的 COMPLEXF 键入作为顶级类型(即 - 代替 COMPLEXF 所有 SIMPLEF 在这个问题的答案的出现)。然后,您可以编写一个 QueryYHandle 程序或类似的,沿着线:

For the sake of example, alter the GetHandle and ReleaseHandle procedures in the linked answer to work with the COMPLEXF type as the top level type (that is - substitute COMPLEXF for all the appearances of SIMPLEF in that answer). You could then write a QueryYHandle procedure or similar, along the lines of:

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 子对象直接 - 使用完全相同的查询* / *中设置的程序作为链接的答案

Now you can work with the handle to the SIMPLEF subobject directly - using the exact same Query*/Set* procedures as in the linked answer.

有没有必要写一个程序来释放由 y_handle 在这种情况下提名的对象,因为与相关联的子对象的寿命组件是由有子对象的对象的生命周期决定的 - 那子对象会自动消失,当ReleaseHandle为 COMPLEXF 超级对象被称为

There's no need to write a procedure to deallocate the object nominated by the y_handle in this case, because the lifetime of the subobject associated with the y component is determined by the lifetime of the object that has that subobject - that subobject will go away when ReleaseHandle for the COMPLEXF super-object is called.

请注意,有在做法没有保护,正如上文所述,由于错误的排序手柄以语言之间传递(例如 - 如果C code不慎被称为意图的过程与<$工作C $ C> COMPLEXF 带手柄竟是一个 SIMPLEF 对象句柄)。如果这是问题的再保护,可以添加,或者通过在与用作不透明句柄对象的C地址捆绑手柄类型并试图Fortran指针与由C地址所指定的对象相关联之前检查句柄类型。

Note that there are no protections in the approach, as outlined above, for the wrong sort of handle to be passed between languages (for example - if the C code accidentally called a procedure intended to work with a COMPLEXF handle with a handle that was actually for a SIMPLEF object). If that is problematic then protections can be added, perhaps by bundling a handle type in with the C address in the object used as the opaque handle and checking that handle type before attempting to associate a Fortran pointer with the object nominated by the C address.

这篇关于包含派生类型Fortran派生类型是从C访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆