call_Lua 似非モジュール:Lua51 汎用・決定版

2017-04-17 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-04-16)の記事「call_Lua 似非モジュール:Lua プログラム汎用化」で、
汎用的なものが作れる目処が立った。

そこで、
再設計を行った。
但し、汎用・決定版と云っても、
所詮 GSL Shell からの LuaJIT の呼び出しで、全く無意味なこと?


さて、今回参考にしたのは、
2月(2017-02-17)の記事「LuaPy_GSL モジュール化」で書いた、
SUB_LuaPy_GSL_Gen.pyに相当するもの。

Lua では、戻り値を文字列に出来たので、

関数名を Exec として、
引数は2つ、戻り値は文字列。


2つの引数について:

第1(IT):整数(int)型データの配列
第2(ST):実行したい Lua ソーステキスト文字列データ

そして、SUB_LuaPy_GSL_Gen.py では、
ST の文字列長を IT[0] で指定していたが、
これは特段指定しなくても出来る。

と云うことで、Lua51_Gen.lua は:
----- Lua51_Gen.lua -----
ffi = require'ffi'
function voidA(s) return ffi.cast( 'void*', s ) end
function IntA(s) return ffi.cast( 'int32_t*', s ) end
function DblA(s) return ffi.cast( 'double*', s ) end
function Exec( IT_, ST_ )
IT=IntA(IT_); SV='OK'
assert( load( ST_ ) )()
return SV
end
でしょうか。
最初の require'ffi' と、
続く function 3つは、汎用で定義しておく。


それで、テスト用 call_Lua51_Gen.gsl は:
以前(2017-04-12)の記事「GSL Shell 学習:見た目の前方参照?(新方式)
で書いた方式で作ってみた。
----- call_Lua51_Gen.gsl -----
ffi=require'ffi'
---------------------- init_After -----------------
F=io.open(arg[0]); w=F:read('*a'); F:close(); fnd=string.find
m='--ini'; _,k=fnd(w,m..'s',1,true); j=fnd(w,m..'e',k,true)
assert(load( string.sub(w,k+2,j-1) ))()
----------- 以下部分が本体 ------------------------
----- 以下 Lua5.1 で実行したいコード群
ss1=[[ print('Lua5.1---')
ffi.cdef[[ int rand(void);
double sqrt(double); ]]
ss2=[[
print( ffi.C.sqrt(3.0) )
print( math.sin(1.0) )
require'lfs'; print( lfs.currentdir() )
t=require'time'; print(t.time())
print(IT[2])
DT=DblA(IT[5]); print(DT[3])
IT[0]=999; SV='ok!'
]]
ST=ss1..']]'..ss2 -- 上記2つの文字列結合
----------------- インタフェースデータ
DT=ffi.new('double[5]', 1.1, 2.2, 3.3, 4.4, 5.5 )
IT=ffi.new('int32_t[6]',1,2,3,4,5,0)
IT[5]=Int32(voidA(DT))
-----------------

L = lua.luaL_newstate()
lua.luaL_openlibs(L)

z = lua.luaL_loadfilex(L, 'Lua51_Gen.lua', 'bt' )
z = lua.lua_pcall(L, 0, 0, 0 ); -- script を一度実行しておく

lua.lua_getfield( L, -10002, 'Exec' ) -- 呼び出す関数
----- -10002 == LUA_GLOBALSINDEX

lua.lua_pushinteger( L, Int32(voidA(IT)) ) -- 第1引数:lua_Integer

lua.lua_pushstring( L, ST ); -- 第2引数:Lua5.1 での実行文

if (lua.lua_pcall(L, 2, 1, 0) ~= 0) then -- 引数 2 個, 戻り値 1 個
printf( nil, 'cannot exec. %s\n', tostring(L)); ----- 中で、実行
os.exit(0)
end
if( lua.lua_isstring(L, -1)) then
SV = lua.lua_tolstring(L, -1, voidA(0)); -- 戻り値
print( ffi.string(SV) ); -- 'OK'~
end
lua.lua_settop(L, -2); -- lua_pop(L,1); 戻り値を pop
lua.lua_close(L)

print( IT[0] )

---------- 以下初期化部分
os.exit(0) ----- これ必須 次の行の1行下の行頭から 初期化部分
--inis
lua = ffi.load( 'lua51' )
ffi.cdef[[ typedef void L_S;
typedef double lua_Number; typedef int32_t lua_Integer;
L_S* luaL_newstate( void );
void luaL_openlibs( L_S* L );

int luaL_loadfilex( L_S* L, const char* filename, const char* mode);
int lua_pcall( L_S* L, int nargs, int nresults, int msgh );

void lua_getfield( L_S* L, int i , const char* name );
void lua_pushinteger(L_S* L, lua_Integer n);
char* lua_pushstring( L_S* L, const char* s);

int lua_isstring( L_S* L, int index );
char* lua_tolstring( L_S* L, int index, size_t* len );
void lua_settop( L_S* L, int m ); // m == -(n) - 1
void lua_close( L_S* L );
]]
Int32 = |s| ffi.cast( 'int32_t', s )
voidA = |s| ffi.cast( 'void*', s )
function printf( f, s, ... )
f = f or io.stdout
f:write(s:format(...))
end
--inie この行の1行上の行末まで
で行ける?

なお、以上の2本のプログラムの他に、
「lua51.dll」「lfs.dll」「time.lua」も一緒に置いておく。


出来たようダ


本日はここまで。


Lua ( GSL Shell ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170315
関連記事
スポンサーサイト

コメントの投稿

管理者にだけ表示を許可する

おきてがみ/blogram
blogram投票ボタン



おきてがみ

最新記事
カレンダー
10 | 2017/11 | 12
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -
月別アーカイブ
カテゴリ
最新コメント
検索フォーム
リンク
プロフィール

<紙>

Author:<紙>
ようこそ。
「パソコンヲタクの雑記帳」
もろもろなことを綴っています。
パソコン ヲタクってねくら?
画像は kami でなく kani です。

カウンター(fc2、i2i) /Google Analytics


i2i(from 2010-08-24)
Total =
Today  =  
Yesterday=
アンチエイジング

Google Analytics
ブックマーク