2

私は、現在取り組んでいるプロジェクトの組み込みスクリプト言語として Python を使用するというアイデアをいじくり回しており、ほとんどのことが機能しています。ただし、Python 拡張オブジェクトをネイティブ C++ ポインターに変換することはできないようです。

これが私のクラスです:

class CGEGameModeBase
{
public:
    virtual void FunctionCall()=0;
    virtual const char* StringReturn()=0;
};

class CGEPYGameMode : public CGEGameModeBase, public boost::python::wrapper<CGEPYGameMode>
{
public:
    virtual void FunctionCall()
    {
        if (override f = this->get_override("FunctionCall"))
            f();
    }

    virtual const char* StringReturn()
    {
        if (override f = this->get_override("StringReturn"))
            return f();

        return "FAILED TO CALL";
    }
};

ブースト ラッピング:

BOOST_PYTHON_MODULE(GEGameMode)
{
    class_<CGEGameModeBase, boost::noncopyable>("CGEGameModeBase", no_init);

    class_<CGEPYGameMode, bases<CGEGameModeBase> >("CGEPYGameMode", no_init)
        .def("FunctionCall", &CGEPYGameMode::FunctionCall)
        .def("StringReturn", &CGEPYGameMode::StringReturn);
}

そしてpythonコード:

import GEGameMode

def Ident():
    return "Alpha"

def NewGamePlay():
    return "NewAlpha"


def NewAlpha():
    import GEGameMode
    import GEUtil

    class Alpha(GEGameMode.CGEPYGameMode):
        def __init__(self):
            print "Made new Alpha!"

        def FunctionCall(self):
            GEUtil.Msg("This is function test Alpha!")

        def StringReturn(self):
            return "This is return test Alpha!"

    return Alpha()

これで、最初の関数をうまく呼び出すことができます:

const char* ident = extract< const char* >( GetLocalDict()["Ident"]() );
const char* newgameplay = extract< const char* >( GetLocalDict()["NewGamePlay"]() );

printf("Loading Script: %s\n", ident);
CGEPYGameMode* m_pGameMode = extract< CGEPYGameMode* >( GetLocalDict()[newgameplay]() );

ただし、Alpha クラスをその基本クラス (上記の最後の行) に変換しようとすると、ブースト エラーが発生します。

TypeError: No registered converter was able to extract a C++ pointer to type class CGEPYGameMode from this Python object of type Alpha

私はネット上で多くの検索を行ってきましたが、Alpha オブジェクトを基本クラス ポインターに変換する方法がわかりません。オブジェクトのままにしておくこともできますが、ポインタとして持つことで、Python を認識しないコードで使用できます。何か案は?

4

3 に答える 3

1

あなたが探している答えではないかもしれませんが、C++ アプリケーションに埋め込むためのChaiScriptを見てください。

彼らのウェブサイトによると、

ChaiScript は、C++ との互換性を考慮してゼロから設計された最初で唯一のスクリプト言語です。これは、ECMAScript にインスパイアされた組み込み関数型言語です。

ChaiScript には、メタ コンパイラ、ライブラリの依存関係、ビルド システムの要件、およびあらゆる種類のレガシー バゲージがありません。At は、公開する C++ 関数とシームレスに連携できます。型について明示的に伝える必要はありません。関数中心です。

ChaiScript を使用すると、プログラムに 3 行のコードを追加するだけで、ビルド手順をまったく変更せずに、文字通りアプリケーションのスクリプト作成を開始できます。

于 2009-08-31T09:23:25.270 に答える
0

参考になるかわかりませんが、Lua のスクリプトで同じ問題が発生しました。Lua からオブジェクトを作成し、いくつかの C++ コードでポインターを介してオブジェクトを処理する必要がありました。次のことを行いました。

  • コンストラクタ、デストラクタ、ファクトリ メソッドを含むすべてのオブジェクトは c++ で記述されています。
  • lua コードがファクトリ メソッドを呼び出してオブジェクトを作成していました。このファクトリ メソッドは、1) オブジェクトに一意の ID 番号を与え、2) ID 番号をネイティブ ポインターにマップする C++ マップにオブジェクトを登録しました。
  • そのため、lua が c++ コードにポインターを渡すときはいつでも、代わりにオブジェクト ID を指定し、c++ コードは ID で実際のポインターを見つけるためにマップを検索しました。
于 2009-08-31T09:22:47.940 に答える