4

C++ で動的ソース コードを処理するには? eval("foo") のようなものを使用することは可能ですか?

ユーザーの選択に応じて呼び出す必要がある関数がいくつかあります。

     void function1 ();
     void function2 ();
     ...
     void functionN ();

     int main (int argv, char * argv [])
     {
         char * myString = new char [100];
         ...
         myString = "1" //user input            
         cout << eval("function"+myString)();
     }

通常はどのように行われますか?

UPD : slacy と clinisbut の回答に基づいて、関数レジストリを作成する必要があると思います。関数へのポインタの配列として作成する必要があると思います。これが質問です。関数へのポインターの配列を宣言するにはどうすればよいですか?

4

14 に答える 14

16

あなたの質問に対する本当の答えはこれです:

extern "C" {
void function1 ();
void function2 ();
void function3 ();
}


 int main (int argv, char * argv [])
 {
     char * myString = new char [100];
     ...
     myString = "function1"; //user input     

     void (*f)() = dlsym(RTLD_NEXT, myString);
     f();
 }

バイナリで定義されている関数を (extern "C" で宣言されている場合はその名前で) 取得し、呼び出すことができます。

Windows では見苦しくなりますが、それでも可能です - GetProcAddress を読んでください

于 2009-05-21T21:14:47.617 に答える
15

C++ はコンパイル済み言語であるため、「eval()」に相当するものはありません。

あなたが言及した特定の例では、入力(文字列)を出力(関数ポインター)にマップする関数レジストリを作成し、結果の関数を呼び出すことができます。

利用可能な C++ インタープリター ライブラリがいくつかありますが、パフォーマンスは非常に低くなりますが、目的を達成できる可能性があります。「C++ インタープリター」を Google 検索します。「 Ch」、「CINT」、「 clipp 」の結果を見てきました

于 2009-05-21T20:52:17.070 に答える
7

本当に必要な場合は、C/C++ インタープリターをプログラムに埋め込むことができます。ただし、代わりに、よりスクリプトに似た言語を埋め込むこともできます。

于 2009-05-21T20:54:20.653 に答える
4

function1 .. functionN を DLL に入れると、単純にそれらを取り出して、dlopen/dlsym を使用して名前で呼び出すことができます。これにより、希望する方法の 90% が得られるでしょう。

于 2009-05-21T21:01:50.717 に答える
4

これが通常どのように行われるかというあなたの質問に答えるために、答えは次のとおりです。そうではありません。

のようなものを使用しなければならないことeval()は、通常、設計上の問題です。本当に必要な場合は、Lua や Python などのスクリプト言語を組み込みます。

于 2009-05-21T21:00:04.823 に答える
4

関数ポインタはどうですか?

于 2009-05-22T09:18:47.367 に答える
2

これは、LUA のようなインタープリター言語を埋め込むのに適したケースです。C++ API への LUA バインディングを作成すると、アプリケーションから LUA コードを介してコードを動的に実行できるようになります。

于 2009-05-21T21:19:28.933 に答える
2

C++ 言語自体は直接それを行うことができません。ただし、プラットフォーム固有の関数を使用して、ユーザー入力 (または何でも) に従って、特定の DLL 内の任意の関数を呼び出すことができます。たとえば、Windows では、GetProcAddress() と LoadLibrary() を探します。

于 2009-05-21T21:03:12.477 に答える
2

これを行うには 2 つの方法があります。

  1. 動的ローディング

    • Windows:これにより、実行可能ファイルのパスが提供GetModuleFileName()されます。自分自身をメモリにロードするためにhModule = NULL使用します。LoadLibrary(Executable_Name)
    • Linux : dloopen()withを使用するNULLと、メモリにロードされます。

    void* (function*)()Windows と Linux の両方で、ポインターを定義できます。これは、パラメーターのないすべての署名で常に機能します。これは、クラス メソッドでは機能しません。

  2. 名前空間システムの使用

    この名前空間は簡単で、Inspect機能とInvokeMemberメソッドを使用して動的にクラス メソッドを呼び出し、クラス内から変数にアクセスできます。

于 2011-11-27T23:37:00.940 に答える
1

関数へのポインタの配列を宣言するにはどうすればよいですか?

この質問に対するCプログラマーの回答:

cdeclを使用します。

cdecl>関数へのポインタ(int、intへのポインタ)としてfunctableを宣言し、doubleを返します

double(* functable)(int、int *)

cdecl>関数(int)へのポインタの配列17としてfunctableを宣言し、doubleを返します

double(* functable [17])(int)

配列がポインタに減衰するのと同じ意味で、関数は自動的に関数へのポインタに変換されることに注意してください。関数のアドレスを取得してポインターに入れるために&は必要ありません。

C ++を使用している場合は、とにかく文字列をマップしたいので、配列の代わりにstd ::map< YourFunctionPointerType >を使用すると役立つ場合があります...

OOアプローチ:

代わりにポリモーフィズムを使用してください。問題をすぐに解決するわけではありませんが、これを行う場合は、関数ごとにクラスを用意するのが理にかなっている可能性があります。

vtableは、基本的に、関数へのポインタのテーブルであることに注意してください。

于 2009-05-30T00:49:44.460 に答える
1

C++ ではできません。これは強制的にコンパイルされた言語です。

とにかく、eval() を実装するために必要な多くの情報が実行時に失われます。

于 2009-05-21T20:52:33.077 に答える
1

関数ポインターの配列または STL リストと、それらの呼び出しをトリガーする文字列を作成します。本当に任意の関数を呼び出す必要がある場合は、RTTI http://en.wikipedia.org/wiki/Run-time_type_informationを調べる必要があります

于 2009-05-21T21:00:08.130 に答える
0

C++ アプリケーション内にコードを埋め込んで評価する最良の方法は、おそらく python のようなスクリプト言語を使用することです。「C++ と Python プログラミング言語の間のシームレスな相互運用性を可能にする C++ ライブラリ」であるBoost.Pythonを使用します。

于 2011-03-09T05:43:54.467 に答える