2011-01-20 18 views
3

私はluaとC++で何かしようとしていましたが、すべての "簡単な"関数が動作します。つまり、luaと他の方法しかし、私は1つの大きな問題があります。C++/lua関数からメンバ関数を呼び出せません

私は小さなゲーム/シミュレータを作っていて、私はlua、odeを使い、自分の小さなインターフェイス(LuaOdeのようなものではない)を作ってみたかったのです。

main class //creates instances of Visual, Physics and LuaAddons 
    v = new Visual(); 
    p = new Physics(); 
    l = new LuaAddons(); 

を次のように私のコードの構造がある今、もちろん私はLuaAddonsから物理学にお話したいと思います。 はそうLuaAddons.cppに私が持っている:

int setWorldGravity(lua_State* L){ 
    float x = luaL_checknumber(L, 1); 
    float y = luaL_checknumber(L, 2); 
    float z = luaL_checknumber(L, 3); 
    //Here I need to somehow talk to p (Physics())  
    return 0; 
} 

私は単に私の.luaファイルと上記の関数でsetWorldGravity(1, 2, 3)を呼び出すことができますこの方法を通し、正しいパラメータを指定してそれに応じて呼び出されました。

ここで問題が発生します。その中でint setWorldGravity私はアプリケーションの物理部分を呼び出して、重力を設定するODE呼び出しを持つ腐食関数を呼び出したいと思っています。 Physics.h中のSO

私が持っている:これらのパラメータを使用して、正しいODE関数を呼び出します

void setWorldGravity(float x, float y, float z); 

それは第一主によって開始されたとき world_が世界に作成され
void Physics::setWorldGravity(float x, float y, float z){ 
    dWorldSetGravity (world_, x, y, z); 
} 

クラス。

しかしLuaAddonsでint setWorldGravity(lua_State* L)は、そのクラスのメンバーではないので、(つまりLuaAddons.hで定義され、そしてそれは静的でなければならなかっただろう場合ではない)私は私の人生は把握することはできませんのために特異的にインスタンス化されたPhysics()にアプローチする方法。関数自体の中から。明らかに、LuaAddonsが同じ世界を持たないので、物理学の新しいインスタンスを作成させることはできません。

何私が試したことはある:

l = new LuaAddons(p); 

(LuaAddons.h中)(LuaAddons.cpp中)

LuaAddons(Physics* p); 

LuaAddons(Physics* p){ 
    phys_ = p; // where phys_ is a private member of LuaAddons.h 
} 

しかし、私がしようとすると追加するには

phys_->setWorldGravity(x, y, z); // error C2065: 'phys_' : undeclared identifier 

この関数はphys_について知りません(大きな驚き)ので、動作しません。

私はLunar.hライブラリを使ってみました。 これで、lua関数をメンバ関数に変形し、.hで宣言して実際にphys _-> stuffを呼び出すことができました。しかし、ライブラリは、そのメンバーを呼び出すために.luaに(心がboggles)、呼び出し元の新しいインスタンスを作るためにあなたを強制的に:

la_ = LuaAddons() 
la_:setWorldGravity(1, 2, 3) 

物理学の部分へのリンクがデフォルトとして行っているが、この方法コンストラクタは渡されたポインタを取得しません。この呼び出しがオブジェクトを通過してODEに適用される部分に到達するとすぐに、nullポインタまたは何かポインタが間違っていると仮定します。

私は、私が実際に同じ物理学の世界が操作されていることを実際に確認したい場合、ほとんど物理的ポインタをluaファイルに渡す必要がありました。しかし、私はちょっと考えていません。

私は長い間読んで申し訳ありませんが、私はむしろ徹底的に重要な詳細を残したいと思います。

ご意見やご感想は非常に高く評価されます。

答えて

3

C++では、メンバー関数は基本的に隠しパラメータを持つ関数です。効果的に、あなたが実際に取得し、

class Foo { 
    const int bar_; 

    public: 
    Foo(int b) : bar_ { } 
    int get_bar() 
    { 
     return bar_; 
    } 
}; 

Foo f(5); 
f.get_bar(); 

をしかし:あなたが書いたC++で

Foo f = Foo_constructor(5); 
Foo_get_bar(f); 

は、この隠しパラメータが thisポインタと呼ばれる(Pythonで、それは selfだ、他の言語は、他の名前を持っています)。

これは、隠されたパラメータを渡してC++のメンバー関数を呼び出すCのような関数です。最も簡単な解決策は、すべてのメンバ関数が取るパラメータに加え、追加のパラメータを取るC関数を記述することです:オブジェクトは、上の関数を呼び出す:

void setWorldGravityWrapper(Physics* p, int x, int y, int z) 
{ 
    return p->setWorldGravity(x, y, z); 
} 

他の技術は、(メンバ関数へのポインタが来るあります心に)、しかし、これはあなたを開始する必要があります。

関連する問題