2015-03-24 109 views
1

作爲此post的擴展,我有派生類型,它們本身具有成員派生類型。實施例下面:包含派生類型的Fortran派生類型可以從C訪問

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等?或者有更好的方法來解決這個問題嗎?

回答

2

可以使用相同的方法。什麼是最好的取決於你認爲什麼是你的C客戶端與Fortran對象進行交互的最佳方式。在編寫太多代碼之前,應該先考慮一些問題。

至於提出的y成分的存在是一個細節的C代碼可能並不需要關心 - 而不是調用sety_a你可以只將其命名爲set_a的過程。

如果要對COMPLEXF類型的組件進行很多操作,並且您希望避免間接級別,或者同一類型的許多此類組件爲COMPLEXF,則可以使用C地址與該組件對應的子對象作爲不透明手柄。

例如起見,改變在linked answerGetHandleReleaseHandle程序與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子對象的工作 - 使用完全相同的查詢* /套*程序作爲鏈接答案。

有沒有必要寫一個程序,取消分配在這種情況下,y_handle提名的對象,因爲與y組件相關的子對象的生命週期由一生的對象,它有子對象確定 - 即子對象會當調用COMPLEXF超級對象的ReleaseHandle時,請離開。

請注意,如上所述,在方法中沒有保護措施,因爲語言之間傳遞的錯誤類型的句柄(例如 - 如果C代碼意外地調用了一個與COMPLEXF句柄配合使用的句柄處理這實際上是一個SIMPLEF對象)。如果存在問題,則可以添加保護,可能是將對象中的句柄類型與用作不透明句柄的對象中的C地址捆綁在一起,並在嘗試將Fortran指針與由C地址指定的對象關聯之前檢查句柄類型。

+0

感謝您的詳細解答。因此,在Fortran中,我仍然可以更改COMPLEXF變量的y SIMPLEF組件,然後C將使用C_LOC安排返回更新的組件。我猜如果我想要的話,我仍然可以在這個階段訪問C端的y子組件,或者我可以將y(已經用C_LOC獲得)與另一個SIMPLEF類型的變量相等,並且C中的值更新。 – Stam 2015-03-25 08:52:13