■ はじめに
* Java から C++ のソースを呼び出すために、JNI(Java Native Interface)を使う
補足:JNA (Java Native Access)
* Java から C++ のソースを呼び出すだけであれば、以下の関連記事のJNAの方がよさそう。https://blogs.yahoo.co.jp/dk521123/36187289.html
■ 作成環境例
* WindowsXP * Eclipse * Visual Studio C++ 2008 Express
■ 作成手順
1) Java側について(その1)
1) Eclipseを立ち上げ、DLLの関数を呼び出すメソッドをnative宣言するクラスを作成 (サンプルの「JniSample.java」を参考に) 2) DLLをロードするクラスを作成 (サンプルの「Main.java」を参考に) 3) C++のヘッダファイルを作成するために... プロジェクトに、build.xml を追加し、サンプルの「build.xml」を参考に修正する 4) Eclipseのメニューにおいて、[Window]-[Show View]-[Ant]を選択 5) Antタブで、アリアイコン(Add Buildfiles)を押下し、手順1-3)で作成した「build.xml」を追加する 6) Antタブで、「create c header」を選択し、三角(緑)アイコン(Run)を押下 ⇒ F5(リフレッシュ)すれば、「com_jni_JniSample.h」ができているはず
2) C++側について(その1)
1) VisualStudioを立ち上げ、[ファイル]-[新規作成]-[プロジェクト]-[Win32]-[Win32プロジェクト]を選択し ソリューション名(例「SampleJni」)を入力し、「OK」押下 2) 「次へ」押下し、「アプリケーションの種類」を「DLL」を選択し、「完了」押下 3) ソリューションエクスプローラのフォルダ「ヘッダーファイル」を右クリックし [追加]-[既存の項目]を選択し、手順1-6)で作成したヘッダーファイル「com_jni_JniSample.h」を選択 4) C++のソースを追加し、C++側のソースを実装 (サンプルの「JniSample.cpp」を参考に) 5) VisualStudioのメニューで、[ツール]-[オプション]-[プロジェクトおよびソリューション]-[VC++ディレクトリ」 を選択し、「ディレクトリを表示するプロジェクト」欄で[インクルードファイル]を選択し、 フォルダアイコン押下し、以下のフォルダを追加し、「OK」押下 * C:\Program Files\Java\jdkX.X.X_XX\include (例「C:\Program Files\Java\jdk1.7.0_25\include」) ⇒ 「jni.h」のありかを示すため * C:\Program Files\Java\jdkX.X.X_XX\include\win32 (例「C:\Program Files\Java\jdk1.7.0_25\include\win32」) ⇒ 「jni_md.h」のありかを示すため 7) ビルドする(「SampleJni.dll」が作成される)
3) Java側について(その2)
1) Eclipseにおいて、該当のプロジェクトを選択した状態で、[File]-[Import]-[General]-[File System] を選択し、「Next」押下 2) 手順2-7で作成したDLL(この例の場合「SampleJni.dll」)を選択し、「Finish」押下 3) 手順1-1) で作成したソース(この例の場合「JniSample.java」)を実行 ⇒ 下記の「出力結果(From Eclipse)」のようになれば成功。
■ サンプル
Java
Main.javapackage com.jni; public class Main { public static void main(String[] args) { JniSample jni = new JniSample(); System.out.println("Result : " + jni.getHellow("Mike")); } }JniSample.java
package com.jni; public class JniSample { static { System.loadLibrary("SampleJni"); } public native String getHellow(String name); }build.xml
<project basedir="./"> <property name="cpdir" value="${basedir}\bin"/> <target name="create c header"> <exec executable="javah"> <arg value="-classpath"/> <arg value="${cpdir}"/> <arg value="-jni"/> <arg value="com.jni.JniSample"/> <!-- ここを変える --> </exec> </target> </project>
C++
com_jni_JniSample.h/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_jni_JniSample */ #ifndef _Included_com_jni_JniSample #define _Included_com_jni_JniSample #ifdef __cplusplus extern "C" { #endif /* * Class: com_jni_JniSample * Method: getHellow * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_jni_JniSample_getHellow (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endifJniSample.cpp
#include "stdafx.h" #include "com_jni_JniSample.h" JNIEXPORT jstring JNICALL Java_com_jni_JniSample_getHellow (JNIEnv *env, jobject thisObj, jstring name){ const char *inputData = env->GetStringUTFChars(name, 0); char result[256]; strcpy_s(result, "Hellow World, "); strcat_s(result, inputData); strcat_s(result, " from Managed C++!!"); env->ReleaseStringUTFChars(name, inputData); return env->NewStringUTF(result); }
出力結果(From Eclipse)
Result : Hellow World, Mike from Managed C++!!
参考文献
JNI作成手順についてhttp://typea.info/blg/glob/2008/06/eclipsevisualstudiojni.html
http://blog.goo.ne.jp/xmldtp/e/75720fd5daebcfd6d6b77292048f6345
C++側のソース
http://www.mitchy-world.jp/java/jni/jni04.htm
http://blog.goo.ne.jp/makoto8002/e/a8e88ca7ed61411843edbac96f368197