2017-03-17 48 views
2

我有一個調用兩個C函數所需的Fortran應用程序。 一個加載一個文件,另一個在文件上運行約200次計算。 我知道一個C DLL不能'保存'加載的結構在一個靜態變量中,以便在計算函數中重用,所以我正在尋找解析一個void *到Fortran並將其發送到C計算函數。Fortran在兩個C函數之間傳遞C結構

的C函數:

__declspec(dllexport) void loadfile(void * file); // Empty pointer should be filled with struct of loaded file 

__declspec(dllexport) void calculate(void * file, double * result); //filled void ptr is used (casted back to my struct first) 

我的Fortran代碼:

module globalFileHolder 
    USE, INTRINSIC::ISO_C_BINDING 
    type(C_PTR), save :: fileModule = C_NULL_PTR  
end module 

加載文件程序:

SUBROUTINE loadcfile() 
    USE, INTRINSIC::ISO_C_BINDING 
    use globalFileHolder 
    IMPLICIT NONE 
    INTERFACE 
     SUBROUTINE loadfile(fm) BIND(C) 
     USE, INTRINSIC::ISO_C_BINDING 
      TYPE(C_PTR) :: fm 
     END SUBROUTINE loadfile 
    END INTERFACE 

    TYPE(C_PTR) :: fms = c_null_ptr  
    call loadfile(fms) 
    fileModule = fms 
    return 
    end 

最後我的程序是應該使用加載的fi樂在計算:

SUBROUTINE calculatec() 
USE, INTRINSIC::ISO_C_BINDING 
    use globalFileHolder 
    IMPLICIT NONE 
    INTERFACE 
     SUBROUTINE calculate(fm,res) BIND(C) 
     USE, INTRINSIC::ISO_C_BINDING 
     TYPE(C_PTR) , VALUE :: fm 
     REAL(C_DOUBLE) , value :: res 
    END SUBROUTINE calculate 
    END INTERFACE 
    TYPE(C_PTR) :: fms 
    REAL(C_DOUBLE) result 
    fms = C_LOC(fileModule) 
    call calculate(fms,result) 
    return 
    end 

現在我目前的問題是,該模塊變量filemodule似乎填補,但它發送到計算函數的變量時,澆鑄等之後,爲空:

myStruct * ms = (myStruct*)file; 

我該在哪裏出錯?

+0

'res'意思是'calculate'的輸出嗎?它具有'value'屬性,但實際參數'result'在調用之前沒有定義它的值。 – francescalus

+0

@francescalus的確如此,我改變了它。但問題在於,如果沒有從加載文件函數訪問加載的文件,就無法計算res。在我檢查fms(filemodule)是否已經被正確地發送到C計算函數之前,我從來沒有計算出res(如:不幸的是它永遠爲空) – Satchmode

回答

1

loadfile接口中fm僞參數的聲明缺少VALUE屬性。

+0

感謝您的貢獻,添加VALUE屬性確實已經修復了一部分內容。該文件現在確實正確地返回到函數,但計算函數仍然接收NULL作爲數據。 *編輯:它可能是存儲在例程之間的模塊是問題? – Satchmode

+0

如所提供的(以及根據問題的francescalus'評論),'loadfile' C函數無法將信息返回到Fortran方面。通過調用loadfile,'fms'的值將始終保持C_NULL_PTR。你確定你的C原型是正確的嗎? – IanH

+0

在計算的res參數上還有一個額外的VALUE屬性。 – IanH