C++からJavaを呼び出す
をテンプレートにして作成
[
トップ
|
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
Visual Studio 2010でJNIを使ってC/C++のコードからJavaのコ...
-----
#contents
-----
*JDKのダウンロードと環境変数の設定 [#h0d2715e]
[[Oracleのサイト:http://www.oracle.com/technetwork/java/j...
OSがx64でもアプリケーションがWin32ならばx86版をインストー...
環境変数PATHに
C:\Program Files (x86)\Java\jdk1.7.0_45\jre\bin\client
を追加する.jdk1.7.0_45の部分は適時バージョンに合わせて書...
また,64ビットアプリケーションの場合は,Program Files (x8...
Windows 7なら
システムのプロパティ → システムの詳細設定 → 詳細設定タブ...
で環境変数を設定できる.
システム環境変数の変数Pathに上記を追加する.ついでに
C:\Program Files (x86)\Java\jdk1.7.0_45\bin
も追加しておくと便利(下記javapなどを使う場合に必要).
*Visual Studioプロジェクトの設定 [#o4152632]
プロジェクトのプロパティで C/C++ → 全般 → 追加のインクル...
C:\Program Files (x86)\Java\jdk1.7.0_45\include
C:\Program Files (x86)\Java\jdk1.7.0_45\include\win32
を追加.
リンカ → 全般 → 追加のライブラリディレクトリに
C:\Program Files (x86)\Java\jdk1.7.0_45\lib
を追加する.
いずれもJDKのバージョンや環境に合わせて適切に書き換えるこ...
リンク時には jvm.lib が必要なので,リンカ → 入力 → 追加の...
#pragma comment(lib, "jvm.lib")
と記述しておく.
*Javaのクラスファイルの準備 [#t680cc90]
Javaのソースコードを準備する.
例えば,以下のような内容をテキストエディタに書き,Test.ja...
#code(java){{
public class Test {
public static String run()
{
return "Hello world!";
}
}
}}
そして,コマンドプロンプトから,
javac Test.java
としてコンパイルする.何もメッセージが出なければ成功して...
成功したらTest.classというファイルができていることを確認...
*C/C++のコードからJavaのクラスを参照する [#neba7f7c]
JNIを使うので以下のようにヘッダをインクルードする.
#include <jni.h>
Javaのコードを実行するために,まずJavaVMを起動する.
#code(java){{
JNIEnv *env;
JavaVM *jvm;
// JavaVM起動オプションの設定
JavaVMOption options[1];
options[0].optionString = "-Djava.class.path=.";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 1;
//vm_args.ignoreUnrecognized = true;
// JavaVMを初期化,起動
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if(res){
cout << "cannot run JavaVM : " << res << endl;
return 1;
}
}}
起動オプション(options)として,クラスファイルがある場所を...
次にクラスを検索して,インスタンス化する.
#code(java){{
// クラス検索
jclass cls = env->FindClass("Test");
if(cls == 0){
cout << "could not found class : Test" << endl;
return 1;
}
// クラス情報をインスタンス化するために<init>メソッドの...
jmethodID cns = env->GetMethodID(cls, "<init>", "()V");
if(cns == NULL){
cout << "could not get <init> method." << endl;
return 1;
}
jobject obj = env->NewObject(cls, cns);
}}
インスタンス化したクラス(obj)を介してメソッド(メンバ関数)...
各メソッドを呼び出すためにはメソッドIDを取得する
#code(java){{
// 各メソッドをインスタンスから呼び出す
// 第3引数のシグネチャは javap -s Test などで調べられる...
jmethodID mid = env->GetStaticMethodID(cls, "run", "()Lj...
if(mid == NULL){
cout << "could not get method : " << "run" << endl;
return 1;
}
}}
GetStaticMethodIDの第2引数は関数名,
第3引数は関数の引数と返値(シグネチャ)を指定している.
シグネチャは,
javap -s Test
とすると調べられる.
インスタンスとメソッドIDがそろったらいよいよ関数を呼び出...
#code(java){{
jstring jstr = (jstring)(env->CallObjectMethod(obj, mid));
}}
返値がない関数だったらCallVoidMethod,int型を返す関数なら...
今回の場合,文字列を返す関数なので,jstring型として文字列...
このままではC/C++コード側で使えないので,char型に変換する.
#code(java){{
// jstring -> char*の変換
const char* cstr = env->GetStringUTFChars(jstr, 0);
char *str = strdup(cstr);
env->ReleaseStringUTFChars(jstr, cstr);
cout << str << endl;
}}
最後にJavaVMを破棄して終了.
#code(java){{
// JavaVMの破棄
res = jvm->DestroyJavaVM();
if(res){
cout << "could not destroy JavaVM : " << res << endl;
return 1;
}
}}
終了行:
Visual Studio 2010でJNIを使ってC/C++のコードからJavaのコ...
-----
#contents
-----
*JDKのダウンロードと環境変数の設定 [#h0d2715e]
[[Oracleのサイト:http://www.oracle.com/technetwork/java/j...
OSがx64でもアプリケーションがWin32ならばx86版をインストー...
環境変数PATHに
C:\Program Files (x86)\Java\jdk1.7.0_45\jre\bin\client
を追加する.jdk1.7.0_45の部分は適時バージョンに合わせて書...
また,64ビットアプリケーションの場合は,Program Files (x8...
Windows 7なら
システムのプロパティ → システムの詳細設定 → 詳細設定タブ...
で環境変数を設定できる.
システム環境変数の変数Pathに上記を追加する.ついでに
C:\Program Files (x86)\Java\jdk1.7.0_45\bin
も追加しておくと便利(下記javapなどを使う場合に必要).
*Visual Studioプロジェクトの設定 [#o4152632]
プロジェクトのプロパティで C/C++ → 全般 → 追加のインクル...
C:\Program Files (x86)\Java\jdk1.7.0_45\include
C:\Program Files (x86)\Java\jdk1.7.0_45\include\win32
を追加.
リンカ → 全般 → 追加のライブラリディレクトリに
C:\Program Files (x86)\Java\jdk1.7.0_45\lib
を追加する.
いずれもJDKのバージョンや環境に合わせて適切に書き換えるこ...
リンク時には jvm.lib が必要なので,リンカ → 入力 → 追加の...
#pragma comment(lib, "jvm.lib")
と記述しておく.
*Javaのクラスファイルの準備 [#t680cc90]
Javaのソースコードを準備する.
例えば,以下のような内容をテキストエディタに書き,Test.ja...
#code(java){{
public class Test {
public static String run()
{
return "Hello world!";
}
}
}}
そして,コマンドプロンプトから,
javac Test.java
としてコンパイルする.何もメッセージが出なければ成功して...
成功したらTest.classというファイルができていることを確認...
*C/C++のコードからJavaのクラスを参照する [#neba7f7c]
JNIを使うので以下のようにヘッダをインクルードする.
#include <jni.h>
Javaのコードを実行するために,まずJavaVMを起動する.
#code(java){{
JNIEnv *env;
JavaVM *jvm;
// JavaVM起動オプションの設定
JavaVMOption options[1];
options[0].optionString = "-Djava.class.path=.";
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions = 1;
//vm_args.ignoreUnrecognized = true;
// JavaVMを初期化,起動
int res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if(res){
cout << "cannot run JavaVM : " << res << endl;
return 1;
}
}}
起動オプション(options)として,クラスファイルがある場所を...
次にクラスを検索して,インスタンス化する.
#code(java){{
// クラス検索
jclass cls = env->FindClass("Test");
if(cls == 0){
cout << "could not found class : Test" << endl;
return 1;
}
// クラス情報をインスタンス化するために<init>メソッドの...
jmethodID cns = env->GetMethodID(cls, "<init>", "()V");
if(cns == NULL){
cout << "could not get <init> method." << endl;
return 1;
}
jobject obj = env->NewObject(cls, cns);
}}
インスタンス化したクラス(obj)を介してメソッド(メンバ関数)...
各メソッドを呼び出すためにはメソッドIDを取得する
#code(java){{
// 各メソッドをインスタンスから呼び出す
// 第3引数のシグネチャは javap -s Test などで調べられる...
jmethodID mid = env->GetStaticMethodID(cls, "run", "()Lj...
if(mid == NULL){
cout << "could not get method : " << "run" << endl;
return 1;
}
}}
GetStaticMethodIDの第2引数は関数名,
第3引数は関数の引数と返値(シグネチャ)を指定している.
シグネチャは,
javap -s Test
とすると調べられる.
インスタンスとメソッドIDがそろったらいよいよ関数を呼び出...
#code(java){{
jstring jstr = (jstring)(env->CallObjectMethod(obj, mid));
}}
返値がない関数だったらCallVoidMethod,int型を返す関数なら...
今回の場合,文字列を返す関数なので,jstring型として文字列...
このままではC/C++コード側で使えないので,char型に変換する.
#code(java){{
// jstring -> char*の変換
const char* cstr = env->GetStringUTFChars(jstr, 0);
char *str = strdup(cstr);
env->ReleaseStringUTFChars(jstr, cstr);
cout << str << endl;
}}
最後にJavaVMを破棄して終了.
#code(java){{
// JavaVMの破棄
res = jvm->DestroyJavaVM();
if(res){
cout << "could not destroy JavaVM : " << res << endl;
return 1;
}
}}
ページ名: