2011-11-11 24 views
1

私はLuaでC++関数を登録しようとしています。LuaのC++関数を登録しますか?

しかし、このエラーを取得:

CScript.cpp|39|error: argument of type 'int (CScript::)(lua_State*)' does not match 'int (*)(lua_State*)'| 

EDIT:

int CApp::SetDisplayMode(int Width, int Height, int Depth) 
{ 
    this->Screen_Width = Width; 
    this->Screen_Height = Height; 
    this->Screen_Depth = Depth; 

    return 0; 
} 

int CScript::Lua_SetDisplayMode(lua_State* L) 
{ 
    // We need at least one parameter 
    int n = lua_gettop(L); 
    if(n < 0) 
    { 
    lua_pushstring(L, "Not enough parameter."); 
    lua_error(L); 
    } 

    int width = lua_tointeger(L, 1); 
    int height = lua_tointeger(L, 2); 
    int depth = lua_tointeger(L, 3); 

    lua_pushinteger(L, App->SetDisplayMode(width, height, depth)); 

    return 0; 
} 

そしてメインで:

lua_register(L, "setDisplayMode", Lua_SetDisplayMode); 
+1

私たちは、このエラーを生成したソースコードのスニペットを見ることができますか? – badgerr

+0

これは簡単な機能です。上記の私の投稿を編集する。 – Cobra

+0

39行目はどちらですか? – Deco

答えて

1

を直接入力することはできません。は、基本的なLua C APIを使用してLuaにC++非静的メンバー関数を登録します。

しかし、C++コードとLuaを簡単に関連付けるためのさまざまなメカニズムのいずれも、そうすることができます。 toLua++,SWIGLuabindなどです。LuaでC++オブジェクトを使用することを真剣にお考えの場合は、独自のバージョンを作成するのではなく、その1つを選択して使用することをお勧めします。私は個人的にLuabindを使用しています(ほとんどの場合SWIGはツールボックスにその場所を持っています)。何らかの形のコード生成をしていないものです。純粋にC++で行われるので、C++ソースファイルを生成するプリパスステップはありません。

+0

返事をありがとう。私はまた、私のアプリでluabindを使用することについて考えている。 – Cobra

6

をあなたは、通常の関数としてクラスのメソッドを使用することはできません、 staticと宣言されている場合を除きます。通常の関数を定義する必要があります。この関数は、メソッドを呼び出すオブジェクトを探し出し、メソッドを呼び出します。

クラスメソッドをC関数のコールバックとして使用することができない主な理由は(そして、Lua APIは純粋なCライブラリであることに注意してください)、コンピュータはメソッドがどのオブジェクトであるべきかを知らないためですの上に呼ばれた。

+0

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

0

アクティブなポインタを静的変数に格納することで、この制限を回避することができます。これは、これらのクラスのうちの2つを同時に動作させることができないという問題を引き起こすが、それは機能する。

static CScript* luaThis; // This is a private variable inside CScript. 

次に、あなたのCScriptコンストラクタ(または「アクティブ」機能のいくつかの種類)の内側に、あなただけ指定することができます。あなたの静的関数が呼び出されたときに

luaThis = this; 

次に、(彼らもプライベートもできますクラス内から登録されている場合は関数)、luaThisポインタを介してすべてのメンバー情報にアクセスできます。

lua_pushinteger(L, luaThis->App->SetDisplayMode(width, height, depth)); 

問題、私が言ったように、これは(それが間違ったことを指している間に、別のLuaの状態から別のコールバックがluaThisを使用するので)一度に一つのアクティブます。CScriptにあなたを制限していることです。これまでに複数のアクティブインスタンスが必要な場合は、受信したlua_State*をキーとして、検索メカニズムを試すことができます。

std::map<lua_State*, CScript*> lookups; // Just an idea, if it comes to this. 

+0

どうしたのかありがとうございました。私はLuabindを最初に試してみることを考えています。 – Cobra

4

答えは実際には驚くほど単純です。あなたの代わりにlua_pushcfunctionのlua_pushcclosureを使用している場合、あなたは、呼び出された関数にパラメータを渡すことができます。

lua_pushlightuserdata(_state, this); 
    lua_pushcclosure(_state, &MyClass::lua_static_helper, 1); 

    int MyClass::lua_static_helper(lua_State *state) { 
     MyClass *klass = (MyClass *) lua_touserdata(state, lua_upvalueindex(1)); 
     return klass->lua_member_method(state); 
    } 
+0

これは良い方法です。詳細については、http://stackoverflow.com/questions/21971131/registering-a-closure-with-luaおよびPIL https://www.lua.org/pil/27.3.3を参照してください。 html – premes

+0

上記のstackoverflowリンクのように、lua_setglobal(_state、 "functionName")という呼び出しを追加するまでは、私にとってはうまくいかなかったことに注意してください。 – premes

関連する問題