包含派生类型Fortran派生类型是从C访问 [英] Fortran derived types containing derived types to be accessible from 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屋!