2016-07-05 343 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

相关问题