2.4 JavaのStringをDLLで解釈する
JavaのStringはそのままDLLで使えませんし、jstringをconst char*にすると、他バイト文字が文字化けします。
これはJavaがUnicodeなのに対し、VC++がShift-JISなためです。
従って以下の手順で正常にDLLで他バイト文字が読めるようにします。
LoadGraph(const char*);
の実装を例に紹介します。
1.
Java側で、StringをShift-JISにしたbyte配列を渡します。
private static native int LoadGraph (byte[] FileName); public static int LoadGraph(String fileName){ try { return LoadGraph(fileName.getBytes("Shift-JIS")); } catch (UnsupportedEncodingException e) { return ERROR; } }
2.
DLL側は、受け取ったbyte配列から文字列を取り出します。
しかし、取り出しただけでは、終端記号が入っていないので、mallocで配列+1の要素ほど確保して、内容をコピーし、
終端記号を入れた上で利用します。もちろん利用後は解放しないといけないので、以下のようになります。
JNIEXPORT jint JNICALL Java_jdx_Dx_LoadGraph
(JNIEnv *env, jobject obj, jbyteArray string)
{
jboolean mIsCopy;
char* mBufBytes = (char *)env->GetByteArrayElements(string, &mIsCopy);
int mLen = env->GetArrayLength(string);
char* mStringc = (char *)malloc(mLen+1);
memcpy(mStringc, mBufBytes, mLen);
mStringc[mLen] = '\0';
int ret = LoadGraph( mStringc );
if (mIsCopy == JNI_TRUE){
env->ReleaseByteArrayElements(string, (jbyte*)mBufBytes, 0);
}
free(mStringc);
return ret;
}
しかし、赤部と青部はお決まり処理なのに、毎回こんなことを書いていたら大変です。そこで・・・
3.
文字列を扱う部分をクラス化します。
よく見たら、上の処理は、赤がコンストラクタ、青がデストラクタで良さそうです。
従って以下のようなクラスを作ってみます。
class BytesString {
public:
BytesString(JNIEnv *env, jbyteArray string){
mEnv = env;
mString = string;
mBufBytes = (char *)env->GetByteArrayElements(mString, &mIsCopy);
mLen = env->GetArrayLength(string);
mStringc = (char *)malloc(mLen+1);
memcpy(mStringc, mBufBytes, mLen);
mStringc[mLen] = '\0';
}
~BytesString(){
if (mIsCopy == JNI_TRUE){
mEnv->ReleaseByteArrayElements(mString, (jbyte*)mBufBytes, 0);
}
free(mStringc);
}
char *GetString(){
return mStringc;
}
private :
JNIEnv* mEnv;
char* mBufBytes;
char* mStringc;
jbyteArray mString;
jboolean mIsCopy;
int mLen;
};
こうすれば、先ほどのLoadGraphの実装は以下のようになります。JNIEXPORT jint JNICALL Java_jdx_Dx_LoadGraph
(JNIEnv *env, jobject obj, jbyteArray string)
{
BytesString bstr(env, string);
return LoadGraph(bstr.GetString());
}
非常にシンプルになりました。
こちらにプロジェクトを置いておきます。
DXライブラリ自体は入っていませんので、DXライブラリのincludeパスはご自分の環境に従って設定して下さい。
Portions of this page are modifications
based on work created and shared by Google and used according to terms
described in the Creative Commons 3.0 Attribution License.
- Remical Soft -