1

次のコードを使用して、Java でクラス RWException (Exception を拡張する) を取得しようとしています。これにより、"getCode()" メソッドを呼び出してエラー コード (int) を取得し、エラーを適切に処理できます。JNI ドキュメントを調べて、次のコードを作成しました... 問題は、パラメーターなしのメソッド getCode() を呼び出そうとすると、AccessViolation 例外が発生することです。探しているクラスとメソッド ID の有効なハンドルを取得します。

jstring o = (jstring)envLoc->CallStaticObjectMethod(cls, mid, jstrUser, jstrPass, jstrGroup);
jthrowable exc = envLoc->ExceptionOccurred();

if (exc) {
    // Get the class
    jclass mvclass = env->GetObjectClass( exc );
    // Get method ID for method
    jmethodID mid = env->GetMethodID(mvclass, "getCode", "()I");
    // Call the method      
    jint code  =  env->CallIntMethod(mvclass, mid);
}

このコードは、次の情報を使用して inVS.NET のデバッグ中に例外を発生させます。

保護されたメモリを読み書きしようとしました

更新 上記の JNI コードを介して呼び出したい Java メソッドは次のとおりです。

public int getCode() {
    return code;
}

mvclass オブジェクトと mid オブジェクトの両方が適切にインスタンス化されており、何か不足していない限り機能するはずです。

更新 2

次のコードを実行すると、 toString() メソッドは同じ概念を使用して機能します。

jstring o = (jstring)envLoc->CallStaticObjectMethod(cls, mid, jstrUser, jstrPass, jstrGroup);
exc = envLoc->ExceptionOccurred();
if (exc) {

    envLoc->ExceptionClear();

    // Get the class
    jclass exccls = envLoc->GetObjectClass(exc);

    // Get method ID for methods 
    jmethodID getCodeMeth = envLoc->GetMethodID(exccls, "getCode", "()I");

    jmethodID getMsgMeth = envLoc->GetMethodID(exccls, "toString", "()Ljava/lang/String;");

    jstring obj = (jstring)envLoc->CallObjectMethod(exccls, getMsgMeth);
    String^ toString = JStringToCliString(obj);

    // this is where the access violation occurs
    jint jcode  =  envLoc->CallIntMethod(exccls, getCodeMeth);
    int code = jcode;
}

したがって、toString() メソッドはオブジェクトの完全なクラス名を返します。これは正しい RWException オブジェクトです。最初の更新 getCode() で概説されているメソッドは public などです...そのため、メモリ アクセス違反エラーが発生する理由がわかりません。

4

3 に答える 3

2
// exc is the exception object
exc = envLoc->ExceptionOccurred();

...

// exccls is the exception CLASS
jclass exccls = envLoc->GetObjectClass(exc);
jmethodID getCodeMeth = envLoc->GetMethodID(exccls, "getCode", "()I");

...

// CallIntMethod(jobject instance, jmethodID method)
jint jcode = envLoc->CallIntMethod(exccls, getCodeMeth);
// exccls is the CLASS, not the object
// so correct would be:
jint jcode = envLoc->CallIntMethod(exc, getCodeMeth);

ああすごい。

そして、コンパイラはこれについて不平を言いjclassませjobjectjstring

于 2012-09-11T10:15:23.563 に答える
2

コードで確認できる唯一の問題は、例外がまだ伝播している間にメソッドを呼び出していることです。envLoc->ExceptionOccurred()は例外オブジェクトを提供しますが、実際には でキャッチする必要がありますenvLoc->ExceptionClear()

于 2012-09-08T09:50:51.747 に答える
1

このコードにはエラー チェックがありません。すべての JNI 操作の結果を確認する必要があります: GetObjectClass()、GetMethodID()、CallXXXMethod() ... たとえば、クラスに getCode() メソッドがあり、それを確認せずに呼び出すとします。

于 2012-09-10T18:54:47.270 に答える