1

私は、プラグインとしてCライブラリを使用できるようにするJavaソフトウェアを実装しています。これらの将来の関数を呼び出すには、Javaでネイティブ関数を作成する必要があります。この関数から、まだ存在していないコードを呼び出すことができます。メソッドのシグネチャは静的ですが、メソッドとクラスの名前は変更される可能性があります。

ロードされたライブラリまたは使用可能な関数を確認する方法はありますか?私がそれがうまくいくことを望む方法は次のようになります:

私のJavaクラスには、関数があります。

public static native void thirdParty(String class, String method, int[] data, int[] params);

これは私のCライブラリの関数を呼び出します。

JNIEXPORT void JNICALL Java_com_ex_app_Native_thirdParty(JNIEnv *, jclass, jstring, jstring, jintArray, jintArray);

そこからクラスとメソッドの名前を取得し、存在する場合はそれらを呼び出し、存在しない場合は例外をスローすることができます。

私が探しているのは、ある種のJavaスタイルのリフレクションですが、Cであるか、そのC++で失敗していると思います。

どうすればこれを達成できますか?

4

4 に答える 4

3

標準的な方法(または実際の標準がないため一般的)

DLL(共有ライブラリ)を作成することです。
その DLL には、ファクトリ オブジェクトへのポインタを返す固定名の「C」関数があります。
その後、ファクトリを使用してオブジェクトを構築できます。

例:

DLL-> Wdigets1.dll      C function -> extern "C" Fac& getWidgetFactory();  
DLL-> BoilerWidget.dll  C function -> extern "C" Fac& getWidgetFactory();  
DLL-> RoundWidget.dll   C function -> extern "C" Fac& getWidgetFactory();

したがって、ロードする dll が何であれ、関数 getWidgetFactory() へのポインタを取得するだけで、ファクトリを使用して適切なウィジェットを構築できます。

この背後にある理由:
ライブラリを動的にロードできるライブラリでは、名前でメソッド/関数を見つけることもできます。ただし、使用する必要がある名前はフルネームです。「C」では、これは明確に定義されています。「C++」では、これはマンゲル化された名前であり、コンパイラ/プラットフォームなどによって異なります。したがって、移植可能なコードは「C」名のみを見つけることができます。

于 2009-06-06T00:12:12.787 に答える
2

C と C++ には実際には Java スタイルのリフレクションはありません (ただし、共有ライブラリでシンボルを検索することでトリックを実行できる場合もあります)。

より一般的なアプローチは、Java でプラグイン インターフェイスを作成することです。次に、外部ライブラリごとに、(できれば) 少量のカスタム Java および/または JNI コードを記述して、プラグイン インターフェイスの呼び出しをバックエンド ライブラリの呼び出しに変換します。

于 2009-06-05T22:44:34.260 に答える
1

これはJNAによく似ています。これにより、基本的に、カスタムJNIコードを記述せずにJavaからネイティブ関数を検索して呼び出すことができます。libffi外部関数ライブラリを使用します。

于 2009-06-06T02:04:08.927 に答える
0

メソッドのシグネチャは静的ですが、メソッドとクラスの名前は変更される可能性があります。

C ++では、メソッド名とクラス名は、呼び出す関数を決定するものであり、JNIが検索するシンボルを作成するために使用されます(これは名前マングリングと呼ばれます)。

希望がある。私が精通しているプラ​​グインシステムでは、各プラグインが特定の名前と署名を持つC関数を実装する必要があります(C ++では、この関数をとしてマークする必要がありますextern "C")。これにより、必要な他の関数やライブラリが呼び出され、プラグインシステムが追跡します。どのDLL(Windows)/ SO(UNIX)がどのプラグインに属し、対応するファイルからマジック関数を呼び出します。

JNIにはファイルと関数名が必要なため、これはプラグインシステムを実装する簡単な方法です。

于 2009-06-05T23:48:57.000 に答える