2017-12-06 4 views
0

私はGUIが最後の行のメソッド呼び出しがに私ができるようになりJNIを使​​用して呼び出しAPI経由で起動されたJavaアプリケーションからCアプリケーションにデータを戻す方法は?

#include <jni.h> 
//... 
JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); 
//... 
(*env)->CallStaticVoidMethod(env, cls, mid, args); 

:のようにメインC(MyAppの)ファイルが見えC

MyApp.c -> Main application - compiled to MyApp 
MyGUI.java -> Java GUI launched programmatically from the C main application - compiled to MyGUI.class 
MyGUI_Print.c -> holds JNI method for testing purpose, called from Java GUI - compiled to libMyGUI_Print.so 

ためInvocation APIから起動としてのJavaアプリが動作していCからプログラムで起動されたJava GUIにデータを送信します。しかし、Javaから実際のCアプリ(MyApp)にデータ(ブーリアンまたはストリング)を送り返すにはどうすればいいですか?Java GUIのボタンをクリックしてみましょう。

JNI経由でJava内からCメソッドを呼び出せることは明らかです。 JavaのGUIアプリ(MyGUI)はテスト目的のために保持している:

private native void print(); 
static { 
    System.loadLibrary("MyGUI_Print"); 
} 

しかし、対応するCファイルので、/ DLLファイルとしてコンパイルする必要があるので、私はもちろん、このライブラリファイル(MyGUI_Print)との間に接続されていませんし、実際のCプログラム(MyAppの)私は、データを必要とするMyGUI_Printから私はしかし、このように印刷することができるよ:。

#include <jni.h> 
#include <stdio.h> 
#include "MyGUI.h" 

JNIEXPORT void JNICALL Java_MyGUI_print (JNIEnv *env, jobject obj) 
{ 
    printf("Hello World!"); 
    fflush(stdout); 
} 

この出力は、実際のCアプリのコンソール出力に達しています。しかし、Cアプリ自体は、これまで "着信"データを知りませんでした。どのように私はプログラム的に反対側(Cアプリ)でこの文字列にアクセスすることができますか?それとももっと良い解決策がありますか?

理論的に私はもちろん理論的にはポーリングを行うことができます。つまり、Cアプリケーションから数秒ごとにJava環境の変数の現在の状態を尋ねることができます。しかし、私はそれが良い方法だとは思わない。

+0

私はそれを理解する方法をあなたに(あなたの周りに関数ポインタを渡したくない場合は、JNAはまた、あなたの関数があるどこのモジュールハンドルを取得し、その名前を経由して機能を得るのを助けることができます)あなたのC++コードでJavaの世界からGUIイベントを受け取る方法を探しています。私は、C++からスタートアップjavaではなく、javaからC++コードを呼び出すことが最善であると思います。あなたがそれを記述する方法から、アクションは常にJava GUIから開始されます。私はあなたが 'このようなライブラリファイルと実際のCプログラムとの間に何の関係もなく、私はデータを必要としている 'ということを理解していません。あなたの入力のための – atoMerz

+0

thx!はい、私はCコードでGUIイベントが必要です。 この場合、CでJava GUIを呼び出す必要があります。逆の方法をとることはオプションではありません。 ライブラリファイルと実際のプログラムの接続に関しては、質問の編集で明らかになることを願っています。 –

+0

私の頭に浮かべる1つの汚い方法は、GUIイベントが発生したときにフラグを設定できることです。次に、C++のスレッドは、そのフラグを定期的にチェックし、イベントが発生したかどうかを確認できます。私がそれを記述した方法は最も簡単な形であり、限界があります。たとえば、フラグをすばやく確認しないと、連続するイベントが失われる可能性があります。これは、単一の変数の代わりにキューを使用することで解決できます。私は詳細にそれに入るつもりはありませんが、あなたはその考えを得るべきです。 – atoMerz

答えて

0

実際には、実行ファイルと仮想JNIライブラリの間に接続があります。彼らは同じプロセスに入っていますので、CコードからJavaコードまで、そしてJavaコードからJNIライブラリのCコードまで、常にハンドルを渡すことができます。そして、図書館はそれを使ってメインモジュールからのものを呼び出すことができます。

つまり、私はJNIの部分をすべてスキップします。関数のアドレスをJavaに渡し、JNA(https://github.com/java-native-access/jna)を使ってその関数を呼び出すことができます。 libffiを内部的に使用します。

関連する問題