0

Javaから呼び出される関数を持つjni dllがあります。問題は、この dll がデフォルト パッケージ (dll "Java_classname_methodname" 内) にすべての Java クラスを持っていることです。この dll のソースを取得することは不可能であり、書き換えには非常に長い時間がかかります。したがって、基本的に、デフォルトとは異なるパッケージで Java からこの dll の関数を呼び出す必要があります。16 進エディタと dll 内のチェックサムとアドレスを変更するいくつかのツールを使用して、dll 内の関数の名前を変更しようと何時間も試みましたが、これについての経験がほとんどないため、私には多すぎます。私はこのルートを非常に好みますが、適切なツールやノウハウを持っていません. だから私が残っているのは、Javaでパッケージ名をハードコードしようとすることです。this で説明されているようにjnaを使用してみまし次のようなことを行うためのスタック オーバーフロー ポスト:

Map options = new HashMap();

options.
    put(
        Library.OPTION_FUNCTION_MAPPER, 
        new StdCallFunctionMapper() {
            public String getFunctionName(NativeLibrary library, Method method) {
                method.setName(method.getName().replace("com.test.", "");
                return super.getFunctionName(library, method);
            }
        }
    );

Native.loadLibrary(..., ..., options);

しかし、メソッドには setName がありません。理想的には、追加のライブラリを使用せずにこれを実行したいと考えていますが、明らかに jna のようなものを使用することに反対しているわけではありません。誰かが尋ねる前に、はい、これはライブラリの使用ライセンスによって許可されています。それが可能であることを知っているので、不可能だとは言わないでください。ただ難しいだけです。どちらの方法で実行する必要があるとしても、私は喜んで作業に取り掛かります (dll を変更するか、外部ライブラリで Java コードを使用するかのいずれか)。ちなみに、最終的には.soおよび.dylibファイルでもこれを行う必要があります(dllほど重要ではありません)。お時間をいただきありがとうございます。

4

1 に答える 1

2

Java から関数が呼び出される JNI dll があります。問題は、この DLL がデフォルト パッケージ (dll "Java_classname_methodname") にすべての Java クラスを持っていることです。

そのため、ネイティブ メソッドを持つ対応する Java クラスもパッケージに含まれていませんでした。

この dll のソースを取得することは不可能であり、書き換えには非常に長い時間がかかります。したがって、基本的に、デフォルトとは異なるパッケージで Java からこの dll の関数を呼び出す必要があります。

正しい。

16 進エディタと dll 内のチェックサムとアドレスを変更するいくつかのツールを使用して、dll 内の関数の名前を変更しようと何時間も試みましたが、これについての経験がほとんどないため、私には多すぎます。

なんとなく関数名をエイリアスできるかもしれませんが、私がこの分野で練習を始めてから約 20 年になります。

私はこのルートを非常に好みますが、適切なツールやノウハウを持っていません. だから私が残っているのは、Javaでパッケージ名をハードコードしようとすることです。

いいえ。ハードコードするパッケージ名はありません。残っているのは、パッケージ内のクラスからパッケージなしでクラス内のネイティブメソッドを呼び出そうとすることです.1.4以降、これは不可能です.

あなたがする必要があるのは次のいずれかです:

  1. リフレクションを介して、パッケージのない Java ネイティブ メソッドを呼び出すことができます。そのため、選択したパッケージに含まれるラッパー クラスを記述して、コードの残りの部分でラッパーを呼び出すことができます。

または

  1. 次のように:

    • 適切なネイティブ メソッドを使用して、選択したパッケージに別の Java クラスを記述します。
    • 既存の DLL からインポート ライブラリを作成します。
    • 別の DLL を作成し、このインポート ライブラリにリンクします。
    • この新しい DLL を Java コードからロードします。
    • この DLLRegisterNativesで初期化時にメソッドを使用して、既存の JNI エントリ ポイントを新しいネイティブ メソッド名とシグネチャで古い DLL に登録します。
    • javah必要なネイティブ メソッド名javapを取得し、必要な Java 署名を取得するために使用します。手で推測しようとしないでください。

これが .so ファイルにどのようにマップされるかは聞かないでください。

于 2016-08-10T05:17:38.287 に答える