2016-07-05 340 views
3

我正在尋找Fortran示例(也是接口函數)將數組作爲參數傳遞給lua函數。我能夠使用fortlua project開始。但提供的示例一次只傳遞一個元素。感謝任何幫助。將數組作爲函數參數傳遞給Fortran

--Lua code 

local q1 
local q2 
function getoutput(qout1, qout2) 
-- qout1 and qout2 are arrays with some dimension 
    q1 = qout1 
    q2 = qout2 
end 

- 在FORTRAN我用

config_function('getoutput', args, 2, cstatus) 

但設置參數表是我在哪裏尋找一些幫助。我猜測下面的代碼是爲標量參數變量而不是數組做的。

!> Evaluate a function in the config file and get its result. 
FUNCTION config_function(name,args,nargs,status) 
    REAL :: config_function 
    CHARACTER(LEN=*) :: name 
    REAL, DIMENSION(nargs) :: args 
    REAL(KIND=c_double) :: anarg 
    INTEGER :: nargs 
    INTEGER :: status 
    INTEGER :: iargs 
    INTEGER(c_int) :: stackstart 

    stackstart = lua_gettop(mluastate) 

    config_function = 0 
    status = 0 


    CALL lua_getglobal(mluastate,TRIM(name)//C_NULL_CHAR) 
    IF (lua_type(mluastate,-1) .eq. LUA_TFUNCTION) THEN 
     DO iargs = 1,nargs 
      anarg = args(iargs) 
      CALL lua_pushnumber(mluastate,anarg) 
     ENDDO 
     IF (lua_pcall(mluastate,nargs,1,0) .eq. 0) THEN 
      if (lua_isnumber(mluastate,-1) .ne. 0) THEN 
      config_function = lua_tonumber(mluastate,-1) 
      CALL lua_settop(mluastate,-2) 
      ELSE 
      ! Nothing to pop here 
      status=-3 
      ENDIF 
     ELSE 
      CALL lua_settop(mluastate,-2) 
      status=-2 
     ENDIF 
    ELSE 
     CALL lua_settop(mluastate,-2) 
     status=-1 
    ENDIF 
    IF (stackstart .ne. lua_gettop(mluastate)) THEN 
     WRITE(*,*) 'The stack is a different size coming out of config_function' 
    ENDIF 
END FUNCTION config_function 
+1

對所有Fortran問題使用標籤[tag:fortran]。 –

+2

你可以將東西放到一個表中,然後將這個表傳遞給函數。但是,您仍然可能會將這些元素逐個推入表格中。我想,如果你正在研究大量的數據,使用userdata可能會更好,儘管這可能會相當複雜。在aotus中,我們也使用將單個標量放入堆棧,儘管您可以遍歷任意數量的元素:https://geb.sts.nt.uni-siegen.de/doxy/aotus/module/aot_fun_module.html – haraldkl

回答

1

爲了擴大對我的評論一點點,這裏是一個小程序,實現與Aotus幫助數組參數:

program aot_vecarg_test 
    use flu_binding, only: flu_State, flu_settop 

    use aotus_module, only: open_config_file, close_config 
    use aot_fun_module, only: aot_fun_type, aot_fun_do, & 
    &      aot_fun_put, aot_fun_open, & 
    &      aot_fun_close 
    use aot_references_module, only: aot_reference_for, aot_reference_to_top 
    use aot_table_module, only: aot_table_open, aot_table_close, & 
    &       aot_table_from_1Darray 

    implicit none 

    type(flu_State) :: conf 
    type(aot_fun_type) :: luafun 
    integer :: iError 
    character(len=80) :: ErrString 
    real :: args(2) 
    integer :: argref 
    integer :: arghandle 

    args(1) = 1.0 
    args(2) = 2.0 

    call create_script('aot_vecarg_test_config.lua') 
    write(*,*) 
    write(*,*) 'Running aot_vecarg_test...' 
    write(*,*) ' * open_config_file (aot_vecarg_test_config.lua)' 
    call open_config_file(L = conf, filename = 'aot_vecarg_test_config.lua', & 
    &     ErrCode = iError, ErrString = ErrString) 
    if (iError /= 0) then 
    write(*,*) ' : unexpected FATAL Error occured !!!' 
    write(*,*) ' : Could not open the config file aot_ref_test_config.lua:' 
    write(*,*) trim(ErrString) 
    STOP 
    end if 
    write(*,*) ' : success.' 

    ! Create a table with data 
    call aot_table_from_1Darray(L  = conf,  & 
    &       thandle = arghandle, & 
    &       val  = args  ) 
    ! Create a reference to this table 
    call flu_setTop(L = conf, n = arghandle) 
    argref = aot_reference_for(L = conf) 

    ! Start the processing of the function 
    call aot_fun_open(L = conf, fun = luafun, key = 'print_array') 
    ! Put the previously defined table onto the stack by using the reference 
    call aot_reference_to_top(L = conf, ref = argref) 
    ! Put the top of the stack to the argument list of the Lua function 
    call aot_fun_put(L = conf, fun = luafun) 
    ! Execute the Lua function 
    call aot_fun_do(L = conf, fun = luafun, nresults = 0) 
    call aot_fun_close(L = conf, fun = luafun) 

    write(*,*) ' * close_conf' 
    call close_config(conf) 
    write(*,*) ' : success.' 
    write(*,*) '... Done with aot_vecarg_test.' 
    write(*,*) 'PASSED' 

contains 

    subroutine create_script(filename) 
    character(len=*) :: filename 

    open(file=trim(filename), unit=22, action='write', status='replace') 
    write(22,*) '-- test script for vectorial argument' 
    write(22,*) 'function print_array(x)' 
    write(22,*) ' for i, num in ipairs(x) do' 
    write(22,*) ' print("Lua:"..num)' 
    write(22,*) ' end' 
    write(22,*) 'end' 
    close(22) 
    end subroutine create_script 

end program aot_vecarg_test 

這使得利用一點點的幫助日常aot_table_from_1Darray創建一個Lua表中的一組實數。看看它的代碼,看看如何將數據放入表中。

然後,我們創建對此表的引用,以便稍後查看它並將其作爲參數傳遞給Lua函數。 該示例創建相應的Lua腳本本身,該腳本定義了一個簡單的函數,該函數需要將單個表作爲輸入並打印每個表項。運行此產生以下的輸出:

Running aot_vecarg_test... 
    * open_config_file (aot_vecarg_test_config.lua) 
    : success. 
Lua:1.0 
Lua:2.0 
    * close_conf 
    : success. 
... Done with aot_vecarg_test. 
PASSED 

哪裏開始和Lua兩線由Lua的功能print_array寫入。

還有其他可能的解決方案,但我希望這至少可以告訴我們如何做到這一點。我們也可以考慮擴展aot_fun_put接口來照顧數組本身。

+1

@kumar與https://bitbucket.org/apesteam/aotus/commits/eb52ed11e6c1c71b2d66f667010995707df81a88它現在也可以將數組傳遞給像這樣的表的函數:real :: args(2);調用aot_fun_put(L,fun,args)。如上所述,這仍然涉及將數組中的每個條目單獨放入表格中,並且可能不適合大量數據,但對於小型矢量應該這樣做。 – haraldkl

相關問題