読者です 読者をやめる 読者になる 読者になる

プログラミングメモ

ソフトウェア開発に関する技術メモ。

JavaとWindowsネイティブを連携させたい

(2009/10/17 更新)


Windowsネイティブプログラミングが要求されるようなソフトウェアを作るならC++C#を使えばよいわけですが、いまさらそれらに習熟したくないという場合にはどうしたらよいか。

Pure Javaでは不足でネイティブが必要なケースとして考えられるのは・・・


JavaからWindowsネイティブへの呼び出しが必要なケース

  • 1-1. レジストリにアクセスする
  • 1-2. イベントログにログを記録する
  • 1-3. 既存のDLLを利用する
  • 1-4. 既存のCOMコンポーネントを利用する
  • 1-5. (SwingやAWTではなく)ネイティブの部品でUIを作成する
  • 1-6. 別のアプリケーションのウィンドウを操作する(操作・テストの自動化など)
  • 1-7. DirectX, Direct3D, DirectShowなど、パフォーマンスの要求される画面描画処理を行う

WindowsネイティブからJavaへの呼び出しが必要なケース

  • 2-1. Javaで作成したソフトウェアをWindowsのサービスとして動かす
  • 2-2. 見せ方としてjava.exeやjarを見せずに、ネイティブアプリケーションと同様に独自の.exeファイルとして見せたい
  • 2-3. DLLやCOMを作りたい?

こんなところ?

Java Win32API実行クラス

http://www.ne.jp/asahi/hishidama/home/tech/soft/java/hmwin32.html

Win32 APIのラッパー。ウィンドウやUI部品関連とCOM関連のAPI 約50個ほどをサポート。別アプリのウィンドウをJavaで操作したいというのが動機で作成された模様。そのためか、ウィンドウを作成するAPIについてはサポートされていない。

Jarwin - a Java/Win32 interoperability project

http://jawinproject.sourceforge.net/

JNIを使わずにCOM, DLLを呼び出せるらしい (legacy な COM/DLLを呼び出せる、とあるが、COM/DLLにレガシーとかそうでないとかがあるんだろうか)。加えて、レジストリやイベントログへのアクセスも可能とのこと。
COM呼び出しのスタブの生成機能もあるらしい。

バージョンが2.0アルファのまま4年以上更新がないのが気がかり。

FuncPtr msgBox = null;

msgBox = new FuncPtr("USER32.DLL", "MessageBoxW");
msgBox.invoke_I(0, "Hello From a DLL", "From Jawin", 0, ReturnFlags.CHECK_FALSE);

J/Invoke

http://www.jinvoke.com/

ネイティブ呼び出しラッパー。有料。http://www.jinvoke.com/gettingstartedを見る限り、個々のAPIのラッパーをJNI経由のDLLで提供しているのではなく、プログラマJavaソース中に宣言したメソッドを自動的にAPIに中継してくれる仕組みらしい。呼び出したいAPIをstatic native付き(本体なし)のメソッドとして記述し、そのメソッドにJ/Invokeが提供するアノテーションを付け、そのアノテーション呼び出し先のDLLを指定する。

public class Example {
   @NativeImport(library="User32")
   public static native int MessageBox(int hwnd, String text, String caption, int type);
}

ということは、このライブラリがどのAPIをサポートしているか、というのは気にする必要がなく、任意のAPIが呼び出せるということか。

Java Native Access (JNA)

https://jna.dev.java.net/

ネイティブ呼び出しラッパー。無料。
J/Invoke同様に、メソッドを宣言するとネイティブに中継してくれる仕組み。
メソッドは、Interface内に宣言する。アノテーションは使用しない。

public interface Kernel32 extends StdCallLibrary { 
    Kernel32 INSTANCE = (Kernel32)
        Native.loadLibrary("kernel32", Kernel32.class);

    void GetSystemTime(SYSTEMTIME result);
}

ユーザー定義インタフェースの実装クラスをNative.loadLibrary内で自動生成しているのだろうか。

xFunction

http://www.excelsior-usa.com/xfunction.html

ネイティブ呼び出しラッパー。有料。J/Invoke同様に汎用と思われる。ネイティブのfunctionの呼び出し方は、リフレクションを使ってJavaメソッドを呼び出すのと似ている。呼び出すfunctionの名前、引数(シグネチャ)を引数にxFunctionオブジェクトをnewすることで、そのオブジェクト経由でネイティブのfunctionを呼び出す。

JNIWrapper

http://www.teamdev.com/jniwrapper/

ネイティブ呼び出しラッパー。有料。J/Invoke同様に汎用と思われる。xFunctionに似ているが、functionの名前を指定すればよく、引数(シグネチャ)の指定は不要に見える。Cの構造体定義から、対応するJavaクラス(ラッパー)を生成するツールも提供されているらしい。

Java Service Wrapper

http://www.tanukisoftware.com/ja/products.php
http://wrapper.tanukisoftware.org/doc/japanese/introduction.html

WindowsサービスとしてJavaアプリケーションを動かすためのソフトウェア。有料(OSSの一部として使う場合は無料?)。VMの監視機能などもあって、安定稼動重視で商用向けと見られる。

launch4j

http://launch4j.sourceforge.net/

Javaアプリをexeにラップしてアイコンをつけたり、JREが無ければJavaのダウンロード画面に誘導してくれたりするらしい。


その他・・・

  • Java COM Bridge COMを呼び出す
  • NativeCall DLLを呼ぶための汎用ラッパー
  • ・・・DirectX, Direct3D, DirectShowのラッパーについては検索するとそれなりにヒットするが未調査


2-3.のパターンについては既存のライブラリは今のところ見つからず。