luaから使える関数をC/C++で作成(hmLJ用)概要luajitで関数作成するのには
の2通りあります。 ここでは、躓きやすいC/C++でluaの関数を作成する方法が説明されています。 全体像を把握する上でも、まずは、一度一通りの簡単な例を実装してみしょう ダウンロード![]() 更新日 2017/04/05
このhmLJ.lib.zipファイルの中身は、「ヘッダーファイル」と「hmLJ.lib」ファイルであり、 C/C++でwin32プロジェクトを作成プロジェクトを作成しましょう。 空のプロジェクトとします。 文字セットはどちらでも良いのですが、秀丸の性質を考慮して、cp932としておきましょう。 ヘッダーファイルやhmLJ.libをコピープロジェクトファイルと同じ場所に「****.h」と「hmLJ.lib」をコピーします。 先ほどコピーしたファイルを、以下のようにプロジェクトファイルに追加しましょう。 これで、luajitのヘッダーファイルや、hmLJ.dll内の関数が利用できるようになりました。 引数の数値を全て足した合計を返す関数の例上図のようにソースを記述していきます。 今回は「mysum.dll」を作成することになりますので、 extern "C" __declspec(dllexport) int luaopen_mysum(lua_State *L) { の部分がそれに相当します。 他の部分は、Luaの関数をC/C++で作る上での基本的な方法となります。 「luaL_register」などをキーワードとして検索するとよろしいかと思います。 #include "lua.hpp" static int myfunc1(lua_State *L) { int n = lua_gettop(L); /* 引数の数 */ lua_Number dsum = luaL_checknumber(L, 1); // 一番上の値 int i; for (i = 2; i <= n; i++) { lua_Number d = luaL_checknumber(L, i); dsum += d; } lua_pushnumber(L, dsum); return 1; // 返り値の個数(スクリプト言語は通常「複数」の値を返すことが出来る) } static const luaL_Reg my_funcs[] = { { "myfunc1", myfunc1 }, { NULL, NULL } }; extern "C" __declspec(dllexport) int luaopen_mysum(lua_State *L) { luaL_register(L, "mysum", my_funcs); return 1; } 出来上がったmysum.dllをマクロファイルと同じ場所に配置出来上がったmysum.dllは、今回のdllの呼び出し元となるマクロやlua(今回はtest.macやtest.lua)と同じ場所に置いておきましょう。 hmLJから利用するためにはhmLJ.dllとマクロファイル(***.mac)やluaファイル(***.lua)は、 hmLJ.dllはhidemaru.exeと同じ場所ですが、各マクロファイルは、 しかし、そのような状態では、hmLJ.dllは今回作成したmysum.dllを発見することが出来ません。 なぜなら秀丸は現在実行中のマクロ(*.mac)自体のディレクトリはちゃんと管理していますが、 そこで、currentmacrodirectoryをlua層に伝達して、lua層では .dllのパス検索の範囲を広げる必要があります。 .mac側からマクロが存在するパス(=mysum.dllが存在するパス)を伝達する以下のものをtest.macとして保存しましょう。 現在のマクロのパスをlua層の変数へと伝達しておきます。 #L = loaddll( hidemarudir + "\\hmLJ.dll"); #_ = dllfunc( #L, "SetStrVar", "currentmacrodirectory", currentmacrodirectory ); #_ = dllfunc( #L, "DoFile", currentmacrodirectory + "\\test.lua" ); freedll( #L ); .lua側で伝達されたパスを検索対象に加える以下のファイルを「test.lua」としましょう。 -- カレントディレクトリがどこにあったとしても、 -- マクロファイルと同じフォルダにある自分で追加したdllを実行可能とするために、 -- cで作成したdllのパスを追加する。 package.cpath = package.cpath .. ";" .. currentmacrodirectory .. "\\?.dll" -- 検索パスを秀丸デバッグモニターに表示 hm.debuginfo(package.cpath) -- 今回作成したライブラリの読み込み require("mysum") -- 引数の数値の合計を秀丸デバッグモニターに表示 hm.debuginfo(mysum.myfunc1(1,2,3,4,5)) このようにすることで、ディレクトリの場所に依存することなく、 |