2016-07-05 17 views
3

私は、配列をlua関数の引数として渡すFortranの例(インタフェース関数も)を探しています。私はfortlua projectを使い始めることができました。しかし、与えられた例は一度に1つの要素を渡します。助けをお待ちしています。Fortranからの関数の引数として配列をluaに渡す

--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 [tag:fortran]を使用してください。 –

+2

テーブルに物を押し込んで、このテーブルを関数に渡すことができます。しかし、おそらく要素を1つずつテーブルにプッシュすることになります。私は、あなたが大量のデータを調べているなら、かなり複雑になるかもしれないが、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 

これはA作成少し手助けルーチンaot_table_from_1Darrayを使用しています実数の配列のLuaテーブル。そのコードを見て、どのようにデータをテーブルに入れることができるかを見てください。

次に、このテーブルへの参照を作成して、後でルックアップしてLua関数の引数として渡します。 この例では、対応するLuaスクリプト自体を作成します。これは、単一のテーブルを入力とし、各テーブルのエントリを出力する単純な関数を定義します。 Luaの始まる2行はLuaの関数print_arrayによって書かれている

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 

:これを実行すると、次の出力が得られます。

他にも解決策がありますが、これがどのように行われるかについての少なくともいくつかの考えを与えることを願っています。 aot_fun_putインターフェイスを拡張して配列自体を処理することも考えられます。

+1

@kumar https://bitbucket.org/apesteam/aotus/commits/eb52ed11e6c1c71b2d66f667010995707df81a88これで、配列を次のようなテーブルとして関数に渡すこともできるようになりました:real :: args(2); aot_fun_put(L、fun、args)を呼び出します。上で説明したように、これは依然として配列の各エントリを個別にテーブルに入れることを含み、おそらく大量のデータに対してはお勧めできませんが、小さなベクトルに対しては行うべきです。 – haraldkl

関連する問題