【Lua組み込み】Luaスクリプトのファイル分割を独自のファイルロード処理で行う方法
require関数やdofile関数のファイルロード処理はカスタマイズできない
Luaスクリプトを書いていてファイル分割をしたくなった場合、Lua標準のrequire関数やdofile関数を使うと思います。
dofile( 'common.lua' ) dofile( 'util.lua' ) -- いろんな処理
問題なのはファイルロード処理を独自の方法で行いたい場合です。require関数やdofile関数はファイルロードにC標準関数のfopenを使うようになっており、ファイルロードをカスタマイズする仕組みも特に用意されていません。なので、ファイルのロード処理をfopenではなく別の方法で行わせたい場合はLuaのソースコードを書き換えるしかありません。面倒くさいですね。
自分でファイルロード処理を行う関数を登録する
よく考えてみると、require関数やdofile関数にこだわる必要はありません。ファイルをロードしLuaスクリプトを実行するC関数を自分で作ってLuaに登録すればいいのです。
例えば、自作する関数の名前をinclude
とした場合Luaスクリプト側はこうなります。
include( 'common.lua' ) include( 'util.lua' ) -- いろんな処理
このinclude関数の実装は以下のようになるでしょう。
// グルー関数の定義 int lua_include_glue( lua_State* p_luaState ) { const char* p_fileName = lua_tostring( p_luaState, -1 ); // include関数の引数を取得 const char* p_luaCode = MyFileLoad( p_fileName ); // 独自のファイルロード処理 luaL_dostring( p_luaState, p_luaCode ); // 文字列をLuaスクリプトとして実行 lua_settop( p_luaState, 0 ); // スタックをクリア return 0; // Luaへの戻り値は無し }
// グルー関数のLuaへの登録 lua_register( p_luaState, "include", lua_include_glue );
ポイントはluaL_dostring
を使うことです。この関数を使うことでLuaにファイルロードさせるのではなく、自分でロードしたスクリプト文字列を実行させることができます。