42

スクリプト言語が最近マッシュルームのように飛び出しているとすれば、私はスクリプト言語に少し錆びています :)

今日、私は、C++ とシームレスに対話するスクリプト言語、つまり C++ クラスを使用できるスクリプト言語があればいいと思いました。私にとって最も重要なことは、C++ またはいくつかの DLL/.SO (およびその .SO ファイル) にコンパイルできることです。 h) それを C++ プログラムにリンクし、スクリプトが定義または実装するクラスを利用できるようにするため。

lua、ruby、python などの一般的なスクリプト言語を埋め込むことができることはわかっていますが、通常、インターフェイスには、提供されたスクリプト コードを評価する何らかの「eval」関数が含まれています。C++ とスクリプト言語を結合するために使用するツールにもよりますが、スクリプトのコールバックを C++ に統合することは多かれ少なかれ簡単に記述できますが、実際に独立したモジュールを記述できるスクリプト言語を見たことがありません。私のプログラムに .h および .so/dll として公開されます (おそらく、C++ コードを生成するスクリプト言語の行に沿って)。

そのようなツール/スクリプト言語を知っていますか?

前もって感謝します。

PD。私はValaや Haskell の GHCに沿って考えてきました。彼らはCを生成しますが、C ++は生成しません...

4

10 に答える 10

35

UPDATE 2020 : 今日、Luaを言語として本当に避けたい場合を除いて、おそらくLua + Sol2/3を使用します。この場合、Lua+Sol2/3 と比較して最適なパフォーマンスではありませんが、Chaiscript が良い候補になります (ただし、長年にわたって大幅に改善されているため、多くの場合、それでも十分です)。Falcon が亡くなってから数年が経ちました、RIP。


次のものは、言語バインディングよりも C++ 統合指向です。

  • ChaiScript - 現在、小さなプロジェクトで試しています。興味深いことに、これは C++ を念頭に置いて作成されており、ヘッダーを含めるだけで機能します! 大きなプロジェクトに適しているかどうかはまだわかりませんが、試してみてください。
  • (もう保守されていません) Falcon - 大きなプロジェクトを試みています。ChaiScript のような「1 つのインクルード埋め込み」ではありませんが、それは非常に柔軟であり、完全に C++ で使用されると考えられているためです (ライブラリ内の C++ コードのみ)。スクリプトの柔軟性 ( ruby​​/python に匹敵)
  • AngelScript - まだ試していません
  • GameMonkey - まだ試していません
  • Io - まだ試していません

スクリプト モジュールを C++ で作成し、それをスクリプト言語に簡単に公開したい場合は、Falcon を使用することをお勧めします。これは完全に C++ で作成されており、すべてのモジュール/ライブラリはそのように記述されています。

于 2010-06-30T21:10:13.280 に答える
21

このコンテキストでよく問われるのは、スクリプトからインスタンス化できるように C++ クラスを公開するにはどうすればよいかということです。答えはしばしばhttp://www.swig.org/のようなものです

あなたは反対の質問をしていて、問題を少し複雑にしているように聞こえます。.h ファイルと .so ファイルを生成するスクリプト エンジンは、実際にはスクリプト エンジンではなく、コンパイラになります。その場合、C++ を使用できます。

スクリプト エンジンはそのようには機能しません。スクリプトと、スクリプトから呼び出すことができる一連の関数を提供するいくつかのコールバックを渡すと、エンジンがスクリプトを解釈します。

于 2010-06-30T15:01:49.087 に答える
21

lua を試す: http://www.lua.org/

lua で C++ クラスを使用するには、以下を使用できます。

バインドを生成するには tolua++ を使用します: http://www.codenix.com/~tolua/

クリーンアップされたヘッダーを入力として受け取り、ハードワークを行う ac ファイルを出力します。簡単で、楽しく、楽しく仕事ができます。

C++ で Lua オブジェクトを使用するには、(field、setField、callMethod、methods、fields) などのメソッドを使用して汎用の Proxy オブジェクトを作成するというアプローチを取ります。

dll が必要な場合は、リソースとして .lua を使用し (Windows では、Linux に相当する適切なものはわかりません)、DllMain でプロキシ オブジェクトを lua コードで初期化できます。

次に、c++ コードはプロキシ オブジェクトを使用して lua コードを呼び出すことができます。この作業を容易にするために、プロキシ内におそらくいくつかのイントロスペクション メソッドがあります。

提供する lua コードを変更するだけで、作成するすべての lua ライブラリに対してプロキシ オブジェクトを再利用できます。

于 2010-06-30T15:21:38.827 に答える
12

これは私の専門分野から少し外れていますが、反対票を投じても構わないと思っています。:-)

Boost::Pythonはあなたが探しているもののようです。マクロ マジックを少し使って作業を行いますが、Python クラスを C++ にかなりきれいに公開します。

于 2010-06-30T14:59:00.113 に答える
5

私は、Io 言語用の C++ バインディング ライブラリである LikeMagic の作成者です。(私は Io の作者ではありません。)

http://github.com/dennisferron/LikeMagic

LikeMagic に関する私の明示的な目標の 1 つは、完全で完全な C++ 相互運用性 (双方向) です。LikeMagic は、ネイティブ Io 型を C++ 型としてマーシャリングし (STL コンテナーと Io のネイティブ List 型の間の変換を含む)、Io 内の C++ クラス、メソッド、フィールド、および配列を表します。Io 環境からIo コードのブロックを渡し、C++ でファンクターとして使用することもできます!!

C++ 型を Io スクリプトで使用できるようにラップするのは、シンプルで迅速かつ簡単です。C++ からスクリプト オブジェクトにアクセスするには、説明したように「eval」関数が必要ですが、テンプレート ベースの型変換とマーシャリングにより、スクリプト文字列の実行結果に簡単にアクセスできます。また、Io block() オブジェクトを C++ ファンクターに変換する前述の機能もあります。

現在、プロジェクトはまだ初期段階ですが、完全に機能しています。ビルド手順と依存関係を文書化するなどの作業をまだ行う必要があります。MSVC でまだサポートされていない C++0x 機能を使用しているため、gcc 4.4.1+ (Microsoft Visual C++ ではない) でのみビルドできます。ただし、Linux と Windows を完全にサポートしており、Mac への移植が計画されています。

ここで悪いニュース: スクリプトで .h ファイルと .so または .dll ファイルを生成して C++ から呼び出し可能にするには、(一種の)コンパイラが必要になるだけでなく、JIT コンパイラも必要になります。これは、(多くのスクリプト言語で、特に Io では) オブジェクトのメソッドとフィールドが実行時までわからないためです。Io では、ライブ オブジェクトにメソッドを追加したり削除したりすることもできます! 最初に、あなたがこれを求めているという事実そのものが、動的言語が何であるかを本当に理解していないのではないかと思います.. しかし、私は、最初に何かを行うための理想的または最も簡単な方法を想像しようとし、そこから実際に可能な方法まで逆算するデザインの方法を信じています. ですから、使いやすさの観点から、あなたが説明した方が使いやすいと思います。

しかし、それは理想的であり、(JIT コンパイルでスクリプト言語を使用して) かろうじて可能ですが、あまり実用的ではないため、あなたが求めているものが本当に欲しいものであるかどうかはまだわかりません. .h および .so/.dll ファイルがスクリプトから JIT され、スクリプトが変更された場合、変更を利用するには C++ プログラムを再コンパイルする必要があります。そもそもスクリプトを使用することの主な利点に違反していませんか?

実用的な唯一の方法は、スクリプトで定義されたインターフェイスが変更されず、スクリプト関数の C++ ラッパーを作成しているだけの場合です。次のような多くの C++ 関数を持つことになります。

int get_foo() { return script.eval("get_foo()"); }
int get_bar() { return script.eval("get_bar()"); }

ラッパー関数の呼び出し元の観点から見れば、これがよりクリーンなコードであることは認めます。しかし、それが必要な場合は、スクリプト言語でリフレクションを使用して、スクリプト オブジェクトに格納されているメソッド リストから .h ファイルを生成してみませんか? この種のリフレクションは、 Io で簡単に実行できます。ある時点で、OpenC++ ソースからソースへのトランスレータを LikeMagic の呼び出し可能なライブラリとして統合する予定です。つまり、文字列を書き出す代わりに、堅牢な C++ コード ジェネレータを使用することもできます。

于 2010-06-30T22:52:13.023 に答える
2

これは Lua で行うことができますが、多くのクラスがある場合は、SWIG や toLua++ などのツールを使用して、グルー コードの一部を生成する必要があります。

これらのツールはいずれも、スクリプト言語が隠されている .h ファイルが背後にあり、C++ コードがスクリプトであることを知らずにスクリプトを呼び出すという、問題の異常な部分を処理しません。これを行うには、次のことを行う必要があります。

  • グルーコードを自分で書きます。(Lua の場合、これは比較的簡単ですが、クラスに入るまでは簡単ではありません。そのため、SWIG や toLua++ などのツールが存在します。)

  • スクリプト インタープリターのある種のグローバルな状態をインターフェイスの背後に隠します。

  • それぞれがスクリプトを使用して実装されている複数の .h ファイルがあると仮定すると、どのファイルがスクリプト言語で状態を共有し、どのファイルが個別のスクリプト状態を使用するかを決定する必要があります。(基本的に持っているのはスクリプト言語用の VM であり、極端な例としては、(a) すべての .h ファイルが同じ VM を共通に使用し、(b) 各 .h ファイルには独自の分離された VM があります。他の選択肢はもっとあります。複雑。)

これを自分で行うことにした場合、Lua テーブルを C++ クラスに変換するグルー コードを作成するのは (プログラムの残りの部分からは Lua コードが C++ のように見えるようにするため) かなり簡単です。C++ を Lua でラップする (C++ オブジェクトが Lua 値のようにスクリプトを参照するようにする) という別の方向に進むと、お尻に大きな苦痛が生じます。

あなたが何をするにしても、あなたの前にはいくつかの仕事があります。

于 2010-06-30T20:34:49.310 に答える
1

良い質問です。私はこれについて自分でよく考えてきましたが、残念ながら、この種のことに対する簡単な解決策はありません。Windows を使用している場合 (そうではないと思います)、C++ および VB で COM コンポーネントを作成することで、このようなことを実現できます (スクリプト言語と見なします)。会話は COM インターフェイスを介して行われます。これは、異なる言語間で相互運用するための優れた方法です。相互運用できる .NET ベースの言語についても同じことが言えます。

私も、このようなものが C++、できればオープン ソースに存在するかどうか知りたいと思っています。

于 2010-06-30T15:09:39.900 に答える
1

Google のV8 エンジンは C++ で書かれているので、プロジェクトに統合できると思います。彼らはこの記事でそれについて話しています。

于 2010-06-30T14:57:40.063 に答える
0

Ring プログラミング言語 http://ring-lang.netを試す

(1) C/C++言語による拡張 https://en.wikibooks.org/wiki/Ring/Lessons/Extension_using_the_C/C%2B%2B_languages

(2) C/C++ プログラムに Ring Interpreter を埋め込む https://en.wikibooks.org/wiki/Ring/Lessons/Embedding_Ring_Interpreter_in_C/C%2B%2B_Programs

(3) C/C++ ライブラリをラップするためのコード ジェネレーター https://en.wikibooks.org/wiki/Ring/Lessons/Code_Generator_for_wrapping_C/C%2B%2B_Libraries

于 2016-03-22T07:25:44.267 に答える
0

Guile (スキーム インタープリター) またはV8 (Google の JavaScript インタープリター - Chrome で使用され、C++ で記述されている) の埋め込みを確認することができます。

于 2010-06-30T14:57:19.033 に答える