More Related Content
Similar to Jjug night seminar201208_lt_cxxからjvm起動
Similar to Jjug night seminar201208_lt_cxxからjvm起動 (16)
Jjug night seminar201208_lt_cxxからjvm起動
- 2. 発表者について
@boochnich
http://d.hatena.ne.jp/torutk/
• 仕事では、C/C++/Javaまんべんなく
– 非Web系分散処理(CORBA、マルチキャス
ト・・・)
– GUI(Swing, X/Motif,GTK+・・・)
– GIS(地図)
• Java読書会BOF現代表
– 1998年~毎月1回開催、通算161回、24冊
http://www.javareading.com/bof/
- 3. JVMを起動するC++コード(骨子)
#include <jni.h>
int main() 説明用につき、
{
JavaVMOption options[2]; エラー処理、動
options[0].optionString = "-Xmx64m";
options[1].optionString = "-Djava.class.path=."; 作確認ログなど
JavaVMInitArgs vm_args; は省略していま
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
す。
vm_args.nOptions = 2;
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(clazz, mid, NULL);
jvm->DestroyJavaVM();
}
- 4. JVMを起動するC++コード(骨子)
#include <jni.h>
int main()
{
JavaVMOption options[2];
options[0].optionString = "-Xmx64m";
options[1].optionString = "-Djava.class.path=.";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 2;
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(clazz, mid, NULL);
jvm->DestroyJavaVM();
}
- 5. JVMを起動するC++コード(骨子)
#include <jni.h>
int main()
{
JavaVMOption options[2];
options[0].optionString = "-Xmx64m";
options[1].optionString = "-Djava.class.path=.";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 2;
JNIEnv* env;
JavaVMに指定するオプションを列挙
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
起動したJavaVMが使用するクラスパス
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
は、システムプロパティ java.class.pathで
env->CallStaticVoidMethod(clazz, mid, NULL);
定義
- 6. JVMを起動するC++コード(骨子)
#include <jni.h>
JavaVMを起動するAPIに渡す設定
int main()
{
JavaVMOption options[2];
JNIのバージョン、JavaVMオプションを指定す
options[0].optionString = "-Xmx64m";
options[1].optionString = "-Djava.class.path=.";
る
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 2;
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(clazz, mid, NULL);
- 7. JVMを起動するC++コード(骨子)
#include <jni.h>
int main()
{
JavaVMOption options[2];
options[0].optionString = "-Xmx64m";
options[1].optionString = "-Djava.class.path=.";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 2;
<jni.h>に定義されている定数(JDK 7u6)
#define JNI_VERSION_1_1 0x00010001
JNIEnv* env;
#define JNI_VERSION_1_2 0x00010002
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
#define JNI_VERSION_1_4 0x00010004
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(clazz, mid, NULL);0x00010006
#define JNI_VERSION_1_6
- 8. JVMを起動するC++コード(骨子)
#include <jni.h>
int main()
{
JavaVMOption options[2];
options[0].optionString = "-Xmx64m";
options[1].optionString = "-Djava.class.path=.";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 2;
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
- 9. JVMを起動するC++コード(骨子)
#include <jni.h>
int main()
{
JavaVMOption options[2];
options[0].optionString = "-Xmx64m";
options[1].optionString = "-Djava.class.path=.";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 2;
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
- 10. JVMを起動するC++コード(骨子)
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 2;
JNIEnv* env;
JavaVM* jvm;
JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(clazz, mid, NULL);
JavaVMを起動します
jvm->DestroyJavaVM();
}
- 11. JVMを起動するC++コード(骨子)
#include <jni.h>
int main()
{
JavaVMOption options[2];
options[0].optionString = "-Xmx64m";
options[1].optionString = "-Djava.class.path=.";
起動したJavaVMにクラスをロードします。
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
クラスはFQCNで記述
vm_args.options = options;
vm_args.nOptions = 2;
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(clazz, mid, NULL);
jvm->DestroyJavaVM();
}
- 12. JVMを起動するC++コード(骨子)
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(
clazz, "main", "([Ljava/lang/String;)V“
);
env->CallStaticVoidMethod(clazz, mid, NULL);
jvm->DestroyJavaVM();
}
クラスのメソッドIDを取得します。
メソッド名
メソッドシグニチャ(引数の型・戻り値型)
- 13. JVMを起動するC++コード(骨子)
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
シグニチャの調べ方
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(
clazz, "main", "([Ljava/lang/String;)V“
C:work> javap -s Hello
);
Compiled from "Hello.java"
env->CallStaticVoidMethod(clazz, mid, NULL);
public class Hello {
public Hello();
jvm->DestroyJavaVM();
}
Signature: ()V
public static void main(java.lang.String[]);
Signature: ([Ljava/lang/String;)V
}
- 14. JVMを起動するC++コード(骨子)
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(clazz, mid, NULL);
jvm->DestroyJavaVM();
}
メソッドを実行します
- 15. JVMを起動するC++コード(骨子)
JNIEnv* env;
JavaVM* jvm;
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
jclass clazz = env->FindClass("Hello");
jmethodID mid = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
env->CallStaticVoidMethod(clazz, mid, NULL);
jvm->DestroyJavaVM();
}
JavaVMを破棄します
- 16. コンパイル・リンク
• Windows (Visual C++)の場合
cl /I"C:Program Files (x86)javajdk1.7.0include“
/I"C:Program Files (x86)javajdk1.7.0includewin32"
/EHsc
launch.cpp
/link
/LIBPATH:"C:Program Files (x86)Javajdk1.7.0lib“
jvm.lib
- 17. 実行
• Windows (Visual C++)の場合
C:work> PATH=%PATH%;”C:Program Files (x86)java
jdk1.7.0jrebinclient”
C:work> launch
Hello, World!
C:work>
- 18. 補足
• jvm.dllを明示的リンクせず暗黙的リンクす
ると柔軟性が増す
– LoadLibraryでjvm.dllを読み込む
– 複数バージョンのJavaVMを使い分ける等
• 非ASCII(日本語)文字列を渡す場合注意
– C/C++側で文字コードを扱うのは悲惨
– C++ 11で光明あり(u8”こんにちは”)
- 19. 情報源
• 公式ドキュメント(日本語訳版)
– http://docs.oracle.com/javase/jp/6/technotes/gui
des/jni/index.html
• 書籍(古いが日本語の唯一のも)
– 「JNI Java Native Interfaceプログラミング」
(ピアソン・エデュケーション刊、1998年)
• 拙著Web記事
– http://www.02.246.ne.jp/~torutk/javahow2/jni.h
tml