4

私は現在、作業中のアプリケーションの1つにLuaを実装する作業を行っています。現在、C apiを使用し、lua_registerを使用して関数を登録していますが、静的および非静的関数ポインターを特定のクラスメソッドに渡せるようにしたいと考えています。

ネット上で特定のライブラリを見つけましたが、それらが提供する全体的な機能はほとんど必要ないので、これを行う簡単な方法があるかどうか疑問に思いました。

ありがとうございました。

4

1 に答える 1

4

複雑なライブラリ API は、多くの場合、SWIGを使用して迅速かつ (ほぼ) 完全にラップできます。この場合に SWIG を使用する利点は、Lua、Perl、Python、Ruby、Java などを含む18 の主要言語でライブラリを使用できる SWIG ベースのラッパーを簡単に構築できることです。

Lua が優先する (そしておそらく唯一の) 関心事である場合は、C で Lua モジュールを構築する戦略の中核で使用することを学ぶことをお勧めしluaL_register()ます。この方法でモジュールを構築する利点は、すべての関数をオーバーヘッドのない単一の名前空間。Lua C 関数の呼び出し規則 ( の場合と同様) に一致しlua_register()、スタックから Lua 引数を収集し、ラップされた関数を呼び出し、戻り値と出力パラメーターを Lua にプッシュするラッパー関数を作成する必要があります。スタック。これを行う方法の概要については、『Programming in Lua』という本を参照してください。初版のオンライン コピーでは、第 26 章でライブラリの作成について説明しています。ですが、Lua 5.0 用に書かれています。Lua を真剣に使用している人には、最新版の PiL のコピーを所有することを強くお勧めします。

残念ながら、Lua 5.1 が 5.0 と最も異なる領域の 1 つは、モジュール (C と Lua の両方) の動的ロードですrequire

Lua 5.1 で動作する C ライブラリの完全な (小さい場合) 例を次に示します。C ファイルでのラッパーの実装から始めます。

#include <lua.h>
#include <luaxlib.h>
#include <math.h>
#undef PI
#define PI (3.14159265358979323846)

static int l_sin (lua_State *L) {
    double r = luaL_checknumber(L,1);
    lua_pushnumber(L, sin(r));
    return 1;
}

static int l_cos (lua_State *L) {
    double r = luaL_checknumber(L,1);
    lua_pushnumber(L, cos(r));
    return 1;
}

static const struct luaL_reg smlib [] = {
    {"sin", l_sin},
    {"cos", l_cos},
    {NULL, NULL}  /* sentinel */
};

int luaopen_sm (lua_State *L) {
    luaL_openlib(L, "sm", smlib, 0);
    lua_pushnumber(L,PI);
    lua_rawset(L,-2,"pi");
    return 1;
}

特に、エクスポートする必要がある唯一の関数は でありluaopen_sm()、その名前は で使用されるモジュールrequireの名前と DLL ファイルの名前に対応している必要があることに注意してください。そのファイルを名前付きの DLL としてコンパイルするとsm.dll(おそらくlibsm.soUnix 系のシステムでは名前が付けられます)、次のようにロードして Lua スクリプトで使用できます。

「sm」が必要
print(sm.sin(sm.pi/3), sm.cos(sm.pi/3));

この例はテストされていませんが、コンパイルして実行する必要があります。のほとんどの関数をラップする完全な例については、Lua で配布されているモジュールのソースをmath.h参照してください。これらの薄いラッパーには多くの繰り返しコードが含まれているため、SWIG などのツールは、各関数の宣言のみを指定して作成できることがよくあります。math

C++ クラスのラッピング メソッドは、原則として似ています。各 Lua 呼び出し可能ラッパー関数には、C++ 側にマップできる引数が必要にthisなります。これは、モジュール静的関数または静的メンバー関数のいずれかとして実装する必要があります。他の引数。SWIG は、この種のラッパーを構築するのが特に得意で、途中で多くの厄介な詳細を隠します。

于 2009-08-17T20:04:42.883 に答える