JNI(Java Native Interface)と呼ばれる仕組みを使います。
これにより、JavaからC++で書いたコードの関数呼び出し(またはその逆)が可能になります。
以下で、C++で書いたgetDataの関数を、Javaのコードから呼び出す例(Windows)を示します。
まず、JavaからC言語のgetDataを実行するためのJavaのクラスを作る必要があります。
そのクラス名をCLangCallクラスとして、以下に示します。またコンパイルしているコマンドも示します。
package clang; //C言語のコードを読むためのコード public class CLangCall { //staticブロックで、最初に一度だけ確実に実行する仕組み(静的初期化子) static { System.loadLibrary("cpplib");//cpplibは、ライブラリの名前 } // 以下が、 C言語の命令の宣言部分 private native byte[] getgetData(byte []a); public static void main(String[] args) { String s = "TEST文字列"; CLangCall me = new CLangCall(); byte[] a = me.getgetData(s.getBytes()); System.out.println(new String(a)); } }
Z:\java>javac clang\CLangCall.java
次に、 このクラスからC言語に必要なヘッダーファイルを生成します。 以下に実行例と生成されたヘッダーファイルを示します。
Z:\java>javah -d Z:\java\clang\cpplib\cpplib clang.CLangCall
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class clang_CLangCall */ #ifndef _Included_clang_CLangCall #define _Included_clang_CLangCall #ifdef __cplusplus extern "C" { #endif /* * Class: clang_CLangCall * Method: getgetData * Signature: ([B)[B */ JNIEXPORT jbyteArray JNICALL Java_clang_CLangCall_getgetData (JNIEnv *, jobject, jbyteArray); #ifdef __cplusplus } #endif #endif
次に、cpplib.dllの名前の
ライブラリを作成するプロジェクトを作成し、
Java_clang_CLangCall_getgetDataの関数を定義します。
以下にそのプログラム例を示します。
#include "clang_CLangCall.h" JNIEXPORT jbyteArray JNICALL Java_clang_CLangCall_getgetData (JNIEnv *env, jobject j_obj, jbyteArray j_array) { // バイト列生成 jbyteArray arrj = env->NewByteArray(5); //// 要素列取得 arrjをコピーして、そのポインタを返す。@ jbyte * elems = env->GetByteArrayElements(arrj, NULL ); //// 要素列取得 j_arrayをコピーして、そのポインタを返す。A jbyte * elems2 = env->GetByteArrayElements(j_array, NULL ); elems[0] = elems2[0] + ('a'-'A'); elems[1] = elems2[1] + ('a'-'A'); elems[2] = elems2[2] + ('a'-'A'); elems[3] = elems2[3] + ('a'-'A'); elems[4] = '-'; // arrjに、elemsから、コピーする。(先頭から5つの要素をarrjへコピー) env->SetByteArrayRegion(arrj, 0, 5, elems); env->ReleaseByteArrayElements(arrj, elems, 0);// @の取得を開放 env->ReleaseByteArrayElements(j_array, elems2, 0);// Aの取得を開放 return arrj; }
最後で、 実行する前にライブラリが実行できるよう、 環境変数 path にライブラリの位置を追加設定し、 それから実行している例です。
Z:\java>set path=Z:\java\clang\cpplib\release;%path% Z:\java>java clang.CLangCall test- Z:\java>