6

WindowsのDLLでJNAを使用しようとしていますが、これまでのところ、 という関数を正常に呼び出すことができましたc_aa_find_devices()。しかし、すべての関数は で始まり、c_aa名前を に変更したいと思いfind_devices()ます。

私が集めたものからこれを行う方法はStdCallFunctionMapperありますが、例でそれを使用する方法のドキュメントを見つけることができません(つまり、DLL関数を名前または序数で、ラップされたJavaライブラリインタフェースの目的の名前にマップする方法) )。ドキュメントの場所に関する提案はありますか?

4

4 に答える 4

4

StdCallMapper を使用してもうまくいきません。名前の一部として埋め込まれたパラメーターの合計バイト長が埋め込まれた奇妙な Windows 標準ライブラリ名をマップすることになっています。それはstd libのみに対して行われるため(推測ですが、99%の機能は当てはまりません)。

dll がすべての関数で共通のプレフィックスを使用している場合は、次のようなものを使用するだけで済みます。

class Mapper implements FunctionMapper{
    public String getFunctionName(NativeLibrary library, Method method) {
       return GenieConnector.FUNCTION_PREFIX + method.getName();
    }
}

GenieConnector.FUNCTION_PREFIXその一般的な接頭辞はどこにありますか。FunctionMapper拡張ではなく実装することに注意してくださいStdCallMapper

于 2009-05-12T21:40:41.857 に答える
2

ドキュメントから、名前を変換する loadLibrary への元の呼び出しで FunctionMapper を提供する必要があります。ただし、標準の呼び出しマッピングも保持する必要があるため、次のようなことを試してください。

Map options = new HashMap();

options.
    put(
        Library.OPTION_FUNCTION_MAPPER, 
        new StdCallFunctionWrapper() {
            public String getFunctionName(NativeLibrary library, Method method) {
                if (method.getName().equals("findDevices") 
                    method.setName("c_aa_find_devices");
                // do any others
                return super.getFunctionName(library, method);
            }
        }
    );

Native.loadLibrary(..., ..., options);
于 2009-02-05T23:27:15.727 に答える
1

すべてのJNAドキュメントは、プライマリWebページJavaDocの概要、およびJavaDoc自体にあります。

上記の例は、一般的なStdCallFunctionMapperによって返される関数名を微調整する必要があるという点で正しい考えです(stdcall呼び出し規約を使用していると仮定します)。ただし、Method.setName()は存在しないため、存在する場合は呼び出したくないでしょう。文字列の結果を取得し、その中のJava関数名をターゲットのネイティブ名に置き換える必要があります。

name = super.getFunctionName();
name = name.replace("find_devices", "c_aa_find_devices");

より一般的には、stdcallの装飾が名前の最後にあるため、返された名前の前に(または先頭の下線の後に)「c_aa_」プレフィックスを付けるだけで済みます。

于 2009-05-12T15:35:40.097 に答える