1. ホーム
  2. スクリプト・コラム
  3. ルア

Lua 5.1でのDLLライブラリの読み込み

2022-02-12 11:01:08

I. lua専用に書かれた拡張DLLの読み込み

    ここではあまり説明されていませんが、requireやpackage.loadlibのメソッドを使用します。

II. lua専用に書かれていない拡張DLLの読み込み

    "Extended dll not written for lua" は、インターフェイスがDLL内のLua登録関数としてエクスポートされておらず、__declspec(dllexport)としてエクスポートされていることを意味します。つまり、 "package.loadlib" メソッドは使用できず、lua5.1ラップの "alien.load()" メソッドを使用する必要があるのです。(Lua5.1 添付ファイル Luaalien.lua)


基本的な使い方です。

1. エイリアンの読み込み

コピーコード コードは以下の通りです。

require("alien")

2、ダイナミックリンクライブラリをロードします。(ここでは、"msvcrt.dll" を例として説明します)
コピーコード コードは以下の通りです。

libc = alien.load("msvcrt.dll")

3. 3. パラメータタイプの指定:(最初のパラメータは戻り値のタイプを示し、後続のパラメータは入力されるパラメータのタイプを示します。)
コピーコード コードは以下の通りです。

  libc.puts:types("void", "string")

Alienは、Luaの数値をCの数値型に変換し、nilをNULLに、文字列をconst char*に、ユーザデータをvoid*のポインタに変換します。関数の戻り値の変換は、その逆(ポインタ型からユーザデータ)になります。

以上の3つのステップでDLLの読み込みが完了し、その後、DLL内の関数を呼び出して、例えば以下のような操作を実装することができます。

コピーコード コードは以下の通りです。

libc.puts("test")

alienがスタックにスペースを確保する必要がある参照型の引数を渡す場合、luaの変数はその値を関数の引数に渡します。

コピーコード コードは以下の通りです。

scanf = libc.scanf
scanf:types("int", "string", "ref int", "ref double ")
_, x, y = scanf("%i %lf", 1, 1) - the last two arguments have no real meaning, they are just to indicate the number of arguments

呼び出し時に23と24.5を入力する。入力された2つのパラメータは本当に関数に渡す必要のあるパラメータである。ref int, ref doubleは、C関数を呼び出してスタックからパラメータを取得するためにスペースを確保する必要があることをalienに伝えるためのもので、呼び出し終了後、戻り結果をスタックに置く(戻り結果とスタック上の他の値を区別するために各C関数も結果数を返すことになる)。そして、lua関数はその結果値を返します。