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>