Luaを使用してプログラムにスクリプトを追加する


Luaは、強力で高速、簡単、組み込みのスクリプト言語です。 これを使用すると、プログラムにスクリプトサポートを簡単かつ迅速に追加できます。
これは、ユーザーがプログラムを個別に調整(カスタマイズ)できるようにする場合、プロジェクト全体を再コンパイルしたくない場合、プログラムのロジックに変更を加える場合、またはエンジンでの作業と作業を分離する場合に必要になることがあります開発者間のロジック(たとえば、ゲームを書くとき)。

この記事では、単純なプログラムを使用して、プロジェクトにLuaを埋め込む例を示します。

Luaを使用するプログラムの例はたくさんあります。 Luaを使用するプログラムの完全なリストとはほど遠いものは、 Lua WikiWikipedia

引数としてディレクトリパスを取り、ファイルとサブディレクトリをリストし、それらをスクリプトに渡す簡単なプログラムの例を示します。 スクリプトは、正規表現を使用して、転送されたファイルのパスで一致するものを探し、見つかった場合、特定のルールに従ってファイルの名前を変更します。

WindowsのVisual Studioで作成した例。 それにもかかわらず、上記のコードは、Windowsに固有のいくつかの機能(ファイルリスト、ファイル名の変更)を除き、少し適応した後、他のプラットフォームでも機能します。 Luaはクロスプラットフォームのスクリプト言語です。

まず、 公式Webサイトにアクセスして、プラットフォーム用のLuaをダウンロードします 。 Windowsの場合、リンカーライブラリ、動的ライブラリ、Luaヘッダーファイルなど、 このアーカイブが適しています。

展開し、Visual Studio設定でヘッダーファイルとリンカーライブラリへのパスを指定します([ ツール]-> [オプション]-> [プロジェクトとソリューション]-> [VC ++ディレクトリ] )。

簡単に説明すると、プロジェクトへのLuaスクリプトの追加は、いくつかのステップで段階的に行われます。

コンソールプロジェクトを作成します。 好きな名前を付けることができます。 まず、ヘッダーファイルを追加します。

extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}

なぜextern "C"ですか? LuaはANSI Cで記述されています。extern “ C”なしでファイルをインクルードしようとすると、次のような多くのエラーが発生します。

unresolved external symbol "char const * __cdecl lua_tolstring(struct lua_State *, int ,unsigned int *)" (?lua_tolstring@@YAPBDPAUlua_State@@HPAI@Z)

これは、Cの呼び出し規約がC ++の規約と異なるためです。

リンカライブラリを接続することを忘れないでください。

#pragma comment (lib, "lua51.lib")

次に、インタープリターのLuaインスタンスを宣言して初期化する必要があります。

//
lua_State *g_LuaVM = NULL;

int _tmain( int argc, _TCHAR* argv[])
{
//
g_LuaVM = lua_open();
...
//
lua_close(g_LuaVM);
}

次に、Luaから呼び出される2つの関数を宣言して実装する必要があります。 最初は、正規表現に一致するファイル名を探します。

int LuaMatchString(lua_State *luaVM)

2番目-ファイルの名前を変更します:

int LuaRenameFile(lua_State *luaVM)

2番目の実装について詳しく説明します。

//
// 1, 0

int LuaRenameFile(lua_State *luaVM)
{
// Lua
int argc = lua_gettop(luaVM);

// -
if (argc < 2)
{
cerr << "RenameFile - wrong number of arguments!" << endl;
// 0 Lua
lua_pushnumber(luaVM, 0);

//
return 1;
}

// ,
// 0 ( )

if (!lua_isstring(luaVM, 1) || !lua_isstring(luaVM, 2))
{
cout << "RenameFile - invalid arguments!" << endl;
lua_pushnumber(luaVM, 0);

//
return 1;
}

// ,
// - - 1, 0, ++

string strSource = lua_tostring(luaVM, 1);
// ,
string strDestination = lua_tostring(luaVM, 2);

strDestination = strSource.substr(0, strSource.rfind('\\') + 1) + strDestination;

int nResult = ( int )::MoveFileEx(strSource.c_str(), strDestination.c_str(), MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH);

// Lua MoveFileEx
lua_pushnumber(luaVM, nResult);

//
return 1;
}

ご覧のとおり、複雑なことは何もありません。渡された引数の数をチェックし、引数のタイプをチェックし、抽出し、ファイルの名前を変更して結果を返します。

次に、エクスポートされた関数についてLuaに知らせる必要があります。これは単純に行われます。

lua_register(g_LuaVM, "RenameFile", LuaRenameFile);
lua_register(g_LuaVM, "MatchString", LuaMatchString);

RenameFileMatchStringは、スクリプトで「表示」される関数の名前です。

すべての作業を実行するスクリプトを作成します。

--
--
-- , -- Lua

function onFileFound(fileName)
patt = MatchString('103([0-9]{1,12}).txt', fileName)

-- patt
-- - ([0-9]{1,12})
-- nil

if patt ~= nil then
-- , 103 XXX
-- : 103180998.txt, XXX180858.txt

RenameFile(fileName, 'XXX' .. patt .. '.txt')
end
end

完全に明確にするために、この関数を呼び出すコードを用意します

// onFileFound
lua_getglobal(g_LuaVM, "onFileFound");
// (fileName )
lua_pushstring(g_LuaVM, strFilePath.c_str());

// onFileFound
if (lua_pcall(g_LuaVM, 1, 0, 0) != 0)
{
// ,
// 0,
// lua_tostring(g_LuaVM, -1)

cerr << "Error calling function onFileFound: " << lua_tostring(g_LuaVM, -1) << endl;
}

プログラムからスクリプトをダウンロードするだけです。

BOOL LoadScript()
{
//
CHAR szScriptPath[1024] = {0};
GetModuleFileName(NULL, szScriptPath, _countof(szScriptPath) - 1);
TCHAR *szSlashPos = strrchr(szScriptPath, '\\');
if (szSlashPos != NULL)
{
szScriptPath[szSlashPos - szScriptPath + 1] = '\0';
}
strcat_s(szScriptPath, _countof(szScriptPath), _T("script.lua"));

//
int s = luaL_loadfile(g_LuaVM, szScriptPath);

// 0 -
// lua_tostring(g_LuaVM, -1)

if (s != 0)
{
cout << "Error while loading script file!" << endl << "Error: " << lua_tostring(g_LuaVM, -1) << endl;

return FALSE;
}

//
s = lua_pcall(g_LuaVM, 0, LUA_MULTRET, 0);

return TRUE;
}

ご覧のとおり、プログラムにLuaスクリプトを埋め込むことは、実際には簡単な作業であり、同時に創造性の広い分野を提供します。

プロジェクトソース

以下は、Luaについて詳しく読むためのリソースのリストです。

公式サイト
ライブデモ
ロシア語のドキュメント
ルアが大好きです。 ルアが大好き
Luaで埋め込みスクリプトを作成する

Source: https://habr.com/ru/post/J74382/


All Articles