More Related Content
Similar to Javaにおけるネイティブコード連携の各種手法の紹介 (20)
Javaにおけるネイティブコード連携の各種手法の紹介
- 2. 自己紹介
久納 孝治 (ひさのう こうじ)
NTTレゾナント・テクノロジーでRemote TestKitを作っています。
「今まで作ったもの」
世界初のケータイJava向けGameBoyエミュレータ (2002年のJavaOneで発表)
http://www.itmedia.co.jp/mobile/0209/26/n_game.html
Skype社の公認のオフィシャルAPIに選定されたSkype4Java
http://www.itmedia.co.jp/enterprise/articles/0710/05/news132.html
Pure JavaによるDalvik VMインタープリタ
http://code.google.com/p/android-dalvik-vm-on-java/
MIDP→iアプリ変換ツール (Opera Miniのiアプリ版で採用)
http://www.itmedia.co.jp/mobile/articles/1106/15/news106.html
など
- 3. Pure JavaによるDalvik VMインタープリタ
AndroidのDalvik VMの仕様書から実装
Java ME上で動作するインタープリタ
(知る限りではクリーンルーム実装では世界初)
サポートしている機能
Dalvik VMの全命令
Java ME CLDCのAPI群
wait・notify等を含むマルチスレッド関連(グリーンスレッドで実現)
- 4. MIDPアプリ→iアプリ変換ツール
Java MEのMIDPアプリのjarをiアプリのjarに静的変換するツール + MIDP APIのランタイム
から構成
静的変換ツールはjavassistライブラリを用いて実装
・javax.microeditionのクラス参照をtv.hisano.doja.runtime.midpパッケージに変換
・System#getProperty呼び出しを独自のクラスメソッド呼び出しに変換
・Class#getResourceAsStream呼び出しを独自のクラスメソッド呼び出しに変換
・などなど
MIDP APIのランタイムをクリーンルーム実装
・ピュアJavaのPNGデコーダを組み込み
・OpenGLを用いた高速な画面描画コンポーネントを組み込み
Opera社とOpera miniのiアプリ版としてリリース(現在は公開終了)
- 21. JavaCPP
Javaクラス + アノテーションでC++クラスを定義すると、クラス定義を元にJNI
コードを生成して使えるようにしてくれるライブラリ
JavaCVの下支えのライブラリ
Apacheライセンス or GPLのデュアルライセンス
javacpp-presetsリポジトリに豊富な定義が存在(CUDA、FFmpeg等)
TensorFlowの定義も追加!
おそらく次のバージョンで楽に使えるように。
https://github.com/bytedeco/javacpp-
presets/blob/master/tensorflow/src/main/java/org/bytedeco/javacpp/tensorflo
w.java
- 26. j2js2ncライブラリの紹介
j2js2ncはEmscripten版JNA
Emscriptenを利用するメリット
ネイティブコードが、マシン語ではなくJavaScriptとなるため、OSやCPUに非依存
Nashorn上でマシン語相当が動作するため、不正なポインタによってプロセスが終了する
ことがない
JNA 4.1の下回りを実装し直して実現しているため、JNAの豊富な高度な機能はそ
のまま利用可能
Javaインスタンスの自動マッピング
メソッド→関数のマッピングルール変更
など
C/C++コード JavaScript
Java
Emscriptenで変換
生成されたJavaScriptコードはJava 8から搭載されたNashorn上で実行
Javaインターフェイス + j2js2ncでC関数を自動バインド
- 27. j2js2ncの具体的な利用の流れ
#include <stdio.h>
#include <stdlib.h>
void hello(char *name) {
printf("Hello, %s!n", name);
}
$ emcc hello.c -s EXPORTED_FUNCTIONS="['_hello']" -o js/hello.js
package jp.hisano.sample;
import jp.hisano.j2js2nc.Library;
import jp.hisano.j2js2nc.Native;
public class Main {
public interface Hello extends Library {
void hello(String name);
}
public static void main(String[] args) throws Exception {
Hello library = (Hello) Native.loadLibrary("hello", Hello.class);
library.hello("j2js2nc");
}
}
hello.dll等に相当するhello.jsを生成
Libraryインターフェイスを継承してメソッドを定義するだけ
でC関数が利用可能
- 29. JNAでの内部処理
#include <stdio.h>
#include <stdlib.h>
void hello(char *name) {
printf("Hello, %s!n", name);
}
Hello library = (Hello) Native.loadLibrary("hello", Hello.class);
library.hello("j2js2nc");
JNA処理
1. StringインスタンスをJNAオブジェクトに変換(NativeString
インスタンスの生成)
2. JNAオブジェクトからネイティブオブジェクトに変換
(malloc関数でバイト配列を確保)
3. libffi経由でネイティブライブラリの関数を呼び出し
GC実行時
1. finalizeメソッド実行時にfree関数が呼び出されて解放
- 30. j2js2ncでの内部処理
#include <stdio.h>
#include <stdlib.h>
void hello(char *name) {
printf("Hello, %s!n", name);
}
Hello library = (Hello) Native.loadLibrary("hello", Hello.class);
library.hello("j2js2nc");
J2js2ncの処理
1. Stringインスタンスをj2js2ncオブジェクトに変換
(NativeStringインスタンスの生成)
2. j2js2ncオブジェクトからネイティブオブジェクトに変換
(_malloc関数でバイト配列を確保)
3. javax.script経由でJavaScript関数を呼び出し
GC実行時
1. finalizeメソッド実行時に_free関数が呼び出されて解放
JNA処理
1. StringインスタンスをJNAオブジェクトに変換(NativeString
インスタンスの生成)
2. JNAオブジェクトからネイティブオブジェクトに変換
(malloc関数でバイト配列を確保)
3. libffi経由でネイティブライブラリの関数を呼び出し