2017-07-16 18 views
1

ハードウェアデバイスとやりとりするアプリケーションを開発しています。ハードウェアの公式アプリケーションに付属のdllファイルを使用して、私はデバイスを初期化し、いくつかの関数をコールバックとして登録して、ユーザーのやりとりによって呼び出されます。このコールバック関数では、Java関数を呼び出してデータを転送する必要があります。ただし、アプリケーション全体は、ちょうど、コールバックでこの呼び出しでエラー・ログなしで終了します。それは、Javaで直接呼び出される関数内で実行された場合ドライバーコールバックでJNI呼び出しが失敗する

jclass cls = env->FindClass("java/lang/String"); 

同じ呼び出しが動作します。 この動作の理由は何ですか? JNIにデバイスドライバ呼び出しを呼び出す方法とはどのように違いがありますか?どんな助けもありがとうございます。

編集:私はVerneeの提案を試み、ドライバスレッドをJVMに添付しようとしましたが、動作は変更されませんでした。さらに、私はprintfの出力を失った。これは残念なことにJNI側をデバッグする私の唯一の選択肢である。彼らはアタッチ操作の前に動作しますが、その後は動作を停止します。

+2

ここをクリックしてください:https://stackoverflow.com/a/12900986/3699139 'JNIEnv *'は、nativeを呼び出すスレッドに対してのみ有効です。 –

+0

@JornVernee他に提案がありますか? – ram

+0

申し訳ありませんが、それは私の唯一の推測でした。 –

答えて

1

Windowsで開発している場合は、Visual Studioを使用してCコードをデバッグすることを強くお勧めします。 Javaプログラムを起動してSystem.loadにブレークポイントを置くことができます。この時点でJavaプログラムが停止し、Visual Studioにアクセスし、ツール>アタッチプロセスからCコードに置かれたブレークポイントで停止できます。その後、Javaコードを再開します。

1 - キャッシュJVMオブジェクト

JavaVM * javaVm; 
(*jenv)->GetJavaVM(jenv, &javaVm); 

2 - キャッシュお使いのJavaのコールバックメソッドを含むクラスのClassオブジェクト:CスレッドからJavaメソッドを呼び出すと、いくつかのpreperationが必要です。あなたは、インスタンスメソッドを呼び出す場合

clazz = (*jenv)->NewGlobalRef(jenv, (*jenv)->FindClass(jenv, "com/something/somepackage/SomeClass")); 

3-、あなたはまた、あなたがへの呼び出しを行う必要がある場合(仮想マシンにネイティブスレッドを取り付け

callback = (*jenv)->NewGlobalRef(jenv, callbackInstance); 

、4-

と呼ばれているインスタンスをcahceする必要があります。 Javaメソッド)

JNIEnv * jenv; 
int errorCode = (*j_javaVm)->AttachCurrentThread(j_javaVm, (void**) &jenv, NULL); 

5 - あなたはJavaのメソッドへの呼び出しを行う必要がある場合

)(呼び出す必要があり、メソッドIDを取得します。
jmethodID methodID = (*jenv)->GetMethodID(jenv, cachedhandlerClass, "methodNameHere", "methodSignetureHere"); 

6メソッド呼び出し

(*jenv)->CallVoidMethod(jenv, cachedCallbackInstance, methodID, param1, param2,....); 

7 deattachネイティブスレッド

(*j_javaVm)->DetachCurrentThread(j_javaVm); 

ステップ1,2及び3は、Java環境を必要とし、彼らがJNI_OnLoad方法で行うか、することができますしてくださいネイティブJavaメソッドの実装では、

+0

私は編集を提出しましたが、承認されていません。あなたはJVMオブジェクトをキャッシュする方法をあなたの答えに含めることができますか?グローバル変数に格納されているときは明らかに機能しませんでした。私はそれをファイルに書き出し、ドライバが私のC++コールバックを呼び出すときにそれを読んで解決しました。 – ram

関連する問題