web-dev-qa-db-ja.com

JavaからWin32 APIメソッドを呼び出す

Wininet.dllの一部のメソッド をJavaプログラムから)呼び出す必要があります。

Javaから作成した新しいDLLを呼び出す方法に関するチュートリアルをたくさん見つけることができますが、既存のDLL。

これにはJNIが関係することは知っていますが、正確にどのようにこれを行うのですか? Wininet.hでjavahを呼び出す必要がありますか? Wininet.hのコピーはどこで入手できますか?既存のdetailedチュートリアルへのポインタで十分です。

35
Paul Reiners
  1. [〜#〜] jna [〜#〜] と思われる 業界標準 希望するものの、「Javaプログラムへの簡単なアクセスを提供するJava code—no [〜#〜] jni [〜#〜] またはネイティブコードが必要です。

  2. Java外部関数インターフェイス - 使用例 もあります
    大丈夫なら、 embedJRuby インタープリターを使用し、 jruby-ffi 経由でwinapiを呼び出すのがはるかに簡単です、 herehere 、および here を参照してください

42
clyfe

私は少し前にこれをしなければなりませんでした。 CコンパイラとWindowsヘッダーファイルが必要です。 mingwは無料で、1つの小さなファイルのみをコンパイルしていたため、mingwを使用しました。

最初にクラスを作成します。以下に例を示します。

package org.whatever.thingy;

public class MyClass {
    // Here is a JNI method, identified by 'native'

    public static native callWin32Thingy(int x, int y, boolean z);

    /* At this point, normal class stuff, other methods, variables, whatever */
}

次に、JDKに付属するコマンドの1つを使用します。これにより、クラスが自動的に取得され、.hおよび.cファイルが生成されます。コマンドは「javah」です。メソッドのシグネチャは次のようになります。

JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy
    (JNIEnv *, jclass, jint, jint, jboolean);

.cファイルには、必要なWindowsヘッダーを含め、メソッドを具体化します。

JNIEXPORT void JNICALL Java_com_whatever_1thingy_MyClass_callWin32Thingy
    (JNIEnv *a, jclass b, jint c, jint d, jboolean e) {
    // Prep steps....

    Win32MethodCallWeCareAbout(x, y, z, hWhatever);

    // Cleanup stuff...
}

メソッドの名前を変更しないで、非常に重要です、それが特定のクラスに関連付けられる方法です。

それが得られたら、それらのファイルをDLLにコンパイルします。 mingwに使用したコマンドは次のとおりです。クラス/パス/などを調整する必要があります。

c:/MinGW/bin/gcc -c -Ic:/MinGW/include -I"c:/Program Files/Java/jdk1.5.0_12/include"
    -I"c:/Program Files/Java/jdk1.5.0_12/include/win32" -D__int64="long long"
    com_whatever_thingy_MyClass_JNIHelper.c

c:/MinGW/bin/gcc -shared -o JNIHelper.dll
    com_whatever_thingy_MyClass_JNIHelper_JNIHelper.o
    -Wl,--add-stdcall-alias,--kill-at,--output-def,def_file

これにより、JNIHelper.dllを含むいくつかのファイルが生成されます。

この時点で、基本的には完了です。 Javaクラスを通常どおり使用し、静的メソッドを呼び出すとWin32コードが実行されます。実行する必要があるのは、ライブラリをインポートすることだけです。私のクラスの静的ブロック)この行が必要です:

System.loadLibrary("JNIHelper");

これにより、Javaは「JNIHelper.dll」という名前のライブラリをロードし、コードにリンクします。ライブラリパスのどこかにJava知っている。

それでおしまい。これは定型的なものですが、簡単なラッピングを行う場合は簡単です。 Java型またはメモリの割り当てに対処する必要がある場合は、悪化します(注:しなかったので、経験がありません)。

全体のチュートリアルがあります ここ (今日私が最初に見つけたのはまともで、ウェブ上で他の人を見つけることができます。 Wikipedia JNIの記事にも詳細があります。

お役に立てれば。

14
MBCook

ネイティブライブラリを直接呼び出すことはできません。これは、メソッドの一部の引数がJava Native Interfaceでサポートされていないためです。

GlueGenと呼ばれるものがあります。これにより、ネイティブDLLに動的にリンクする別個のバイナリが作成されます。生成されたバイナリはJNIと互換性があるため、Javaから呼び出し可能です。

http://en.wikipedia.org/wiki/Gluegen

Wininet.dllのヘッダーファイルを取得するには、おそらくプラットフォームSDK(またはWindows SDK、最新バージョン)が必要です。このヘッダーファイルを含むオンラインリポジトリをネットで検索することもできます。

GlueGenには、ヘッダーファイル、ANSI Cコンパイラなどが必要です。

GlueGenを必要としないNativeCallと呼ばれるあまり知られていないライブラリもあります。すでにJava互換のバイナリがあります。 Javaからの要求に応じてDLLを動的にロードするため、これは明らかに低速です。私はまだこれを使用していませんが、有望に聞こえます:

http://johannburkard.de/software/nativecall/

3
Pindatjuh