luaのオンメモリインクルード

luaでメモリ上のコードをインクルードする方法についてです。
「require」命令を使うと基本的に同フォルダの該当するファイルを勝手に読み込みますが、cアプリから、しかもファイルが存在せず、メモリ上のファイルデータの場合は勝手に読み込んでくれません。
なので、cアプリ側で色々と読み込み処理を制御してやる必要があります。


まず、インクルードするコード(hogelib)と実行するコード(test)を用意しましょうか。

-- hogelib.lua
function hoge()
  return "hoge!hoge!";
end;

-- test.lua
--require("hogelib");  --今回はコメントアウトしないとダメ
function run()
  print( hoge() );
end

オンメモリのファイルをインクルードさせる場合は、ファイル読み込み部分のrequireが不要になります。
そのかわり、c側でこれに相当する処理を行わなければなりません。

// c
luaL_loadbuffer(vm,MemoryStream_hogelib.MemryPointer...);
lua_pcall(vm, 0, 0, 0);
luaL_loadbuffer(vm,MemoryStream_test.MemoryPointer...);
lua_pcall(vm, 0, 0, 0);
//run()実行
lua_getglobal("run")
lua_pcall

hogelibのコードを読み込んでpcallでセットアップさせます。
言語だとインクルードはコードを埋め込むというニュアンスですが、luaではそのファイルを実行して関数(変数)をグローバルに登録するという動作に置き換わります。
ですんで、動的に関数を変えたり(override)とか出来るんでしょうけど、今回はおいておきましょう。


さて、luaにはモジュールという概念があります。
これを使用する場合は、上とは逆にrequireが必要になりますので注意してください。

-- hogelib.lua
module("hogelib",package.seeall);
function hoge()
  return "hoge!hoge!";
end;

-- test.lua
require("hogelib");
function run()
  print( hogelib.hoge() );
end

c側の処理は上と同じです。


とうわけで、オンメモリのインクルードを行いました。
これで問題なのは、インクルード候補のファイルをc側で処理するため、あらかじめ候補ファイルをなんらかの方法で知る必要があります。
もしコンパイル済みファイルを使用しないのであれば、「--uses=hogelib」というように、コメントに仕込んでおいて、c側で読み取ってあげるという手法も考えられます。
ただ、やっぱりコンパイル済みにしておくとロード時間がかなり節約できるので、別ファイル(.inc)に設けておくのがよろしいかなーとおもいます。
上記の例だとこんな簡単なもんでいいでしょう。

// test.inc
uses=hogelib

実際はincludeよりもuses(一回読み込んだら次回からパス)処理を実装したほうが、なにぶん便利だとおもいます。
マクロ命令を実装するよりかはこの方が楽でしょうし。