4

純粋仮想クラスの C++ オブジェクトを期待する関数に、純粋仮想 C++ クラスから派生したクラスの Lua オブジェクトを渡したいと思います。これどうやってするの?

私は lua と luabind が初めてなので、ご容赦ください。

C++ の場合:

struct A {
  virtual void foo() = 0;
};

void do_something(A* a) {
  a->foo();
}

ルアの場合:

class 'MyA' (A)
....
function MyA:foo()
  print('hi')
end

再び C++ で:

... // somehow create an instance of MyA class and named myA
    // How? 
    // Maybe the result of a call to "MyA()"?

do_something(myA);
4

4 に答える 4

2

LuaBind ドキュメントのセクション10.1を参照してください。基本的には、基礎となる Lua 実装へのパススルーとして機能する単純な C++ ラッパーを LuaBind クラスに提供します。このドキュメントから次のことに注意してください。

virtual void f(int a) 
{ 
    call<void>("f", a); 
}

call("f", a) は Lua 'f' 関数を呼び出し、引数 a を渡します。

于 2009-04-29T21:39:21.863 に答える
2

純粋仮想関数を実装してから Lua コードを呼び出す C++ クラスを作成する必要があります。実装は複雑すぎて、ここに入れることはできません。

基本的な擬似コード:

// C++
struct LuaA : public A
{
  LuaA(const std::string &luacode)
    : myLuaHandler(luacode)
  {
  }

  virtual void foo()
  {
    myLuaHandler.call("MyA:foo()");
  }
}

この例は非常に高レベルですが、やりたいことが簡単ではないことを示すためのものです。実際に Lua コードに公開したいのは、新しい「LuaA​​」です。

一般に、Lua やその他のスクリプト言語に公開するために C++ をラップする場合は、 SWIGを使用することを好みます。SWIG は、興味のある仮想メソッド (SWIG 用語では「ディレクター」と呼ばれる) のこのオーバーロードをサポートしていますが、Lua/SWIG はディレクターをサポートしていないことに注意してください。Java、C#、Ruby、Perl、および Python はすべて SWIG でディレクタをサポートしています。Lua でサポートされていない理由が正確にはわかりません。

Lua は継承をサポートしていないため、実現したいことの正確なセマンティクスを提案した方法では実現できない可能性があります。

おそらく、他の誰かが Lua 側のより良い答えを持っているでしょうか?

于 2009-04-29T21:14:01.893 に答える
2

申し訳ありませんが、あなたが尋ねた質問に直接答えることはできませんが、代わりに個人的な経験からのアドバイスを提供します。

Lua を初めて使用する場合は、最初のバインディングを生の Lua APIで記述し、そのようなオブジェクト指向レイアウトを使用しないことを真剣に検討する必要があります。少なくとも、実際に何が起こっているのかを理解できます。

Lua API は、単独で使用するのに非常に快適です。余分なオーバーヘッドは発生せず、何が起こっているかを完全に制御できます。Luabind ライブラリの開発は、現時点では少し古くなっています (ただし、復活したように見えます)。

Lua 側、特に C++ 側で C++ クラスからの派生を本当に模倣する必要があるかどうかを検討する必要があります。このようなことは Lua にとってそれほど自然ではなく、実装するにはかなりのオーバーヘッドが必要です。さらに、C++ では、別の言語に対して非ネイティブな呼び出しを行っているという事実を隠しています。十分に文書化されていない限り、これはパフォーマンスの問題の原因となる可能性があります。

数年前に Lua を使い始めたとき、Luabind を使用して、C++ オブジェクトからの派生を模倣して、あなたと同じ方法でバインディングを作成していました。現在、私は純粋な Lua API と単純化された手続き型 (オブジェクト指向ではなく) 言語間インターフェースを使用しています。私は結果にとても満足しています。

于 2009-04-30T05:57:39.950 に答える
1

C++ で純粋な仮想クラスをサブクラス化し、(Aaron と lefticus のソリューションによると) luabind で開始する可能性があります。このオーバーヘッドが大きすぎる場合は、単純な Lua C スタック操作 API を使用します (Alexander によると)。

したがって、ここには誰も答えがありません。後で結果をコメントで投稿します。

みんな、ありがとう!

于 2009-04-30T16:08:54.863 に答える