2016-11-15 3 views
0

JNI仕様では、関数をextern "C"ブロックに配置する必要があります。しかし、Cリンケージは型記述子を含んでいません。したがって、Javaコードでネイティブメソッドを呼び出すとき、jvmは、リンケージ内のネイティブコードの引数番号/順序/型と戻り値の型とJavaネイティブ定義が互換性があるかどうかを確認できますか?jniは、jniを呼び出すときに引数と戻り値の型をチェックするにはどうすればよいですか?どのようにこの型チェックを実装するには?

また、このような型チェックを実装する方法を理解したいと思います。私はすでにdlopen()/dlsym()/dlclose()をLinuxプラットフォーム上で使用できることを知っていますが、タイプ記述子を取得できないため、タイプチェックを進めることができません。タイプ記述子でダイナミックライブラリとシンボルをロードする他の方法はありますか?私はこのライブラリのロードを実装し、JustVMと呼ばれる、私たちが作った「輪」プロジェクトに型チェックをするつもりです

、ここでのレポの:
https://github.com/lfkdsk/JustVM

+0

実行時に、パラメータの数/型/名前(および戻り値)は単純には分かっていないため、「チェック」することはできません。 –

答えて

1

JVMは、ネイティブメソッドの型の安全性を強制しません。それは名前だけを気にします。

など。次のコードはうまくコンパイルされ、ライブラリは正常に読み込まれます。ただし、nativeMethodを呼び出すと、戻り値-1がObjectとして扱われるため、JVMはクラッシュします。

Test.java

public class Test { 

    public static void main(String[] args) throws Exception { 
     System.loadLibrary("test"); 
     new Test().nativeMethod(0, 1); 
    } 

    private native Object nativeMethod(long a, int b); 
} 

test.cの

#include <jni.h> 

JNIEXPORT jint JNICALL Java_Test_nativeMethod(JNIEnv* env, jobject self) { 
    return -1; 
} 

あなたは動的リンクのための引数の型についての情報を保持したい場合は、あなたが何らかの形でそれをエンコードする必要があります関数名Name manglingを参照してください。

-1

JNI仕様では、「関数がexternに置かなければならない必要Cブロック。しかし、Cリンケージは型記述子を含んでいません。

しかし、javahによって生成された関数名はあります。

Javaコードでネイティブメソッドを呼び出すと、jvmはリンケージ内のネイティブコードの引数番号/順序/型と戻り値の型とJavaのネイティブ定義が互換性があるかどうかを確認できますか?

これは、必要な引数などに基づいて名前を再生成することで検索するので、見つからない場合はLinkageErrorをスローします。

また、このような型チェックを実装する方法を理解したいと思います。

これも同様です。

+0

OpenJDKとOracle JDKの 'javah'によって生成されたJNI関数名は、ネイティブメソッドがオーバーロードされていない限り、メソッドの引数と戻り値の型に依存しません。ネイティブメソッドルックアップのためにJVMによって構築されたシンボル名は、引数または戻り値の型にも依存しません。 – apangin

+0

@apanginはい、私はまた、ndk-buildによってビルドされたようなライブラリを逆アセンブルすることで確認しました。 しかし、私はまだJVMが引数の型をチェックしてシンボルの型を返して、VMにロードされたバイトコードが必要とするネイティブ関数があることを確認していません。シンボル名自体もCリンケージもタイプ。 –

関連する問題