(JNI-шное відображення String) і навпаки. Практично у всіх описах і прикладах JNI для цього використовується пара функцій GetStringUTFChars ()/ReleaseStringUTFChars (). Підступні буржуїни і тут приготували засідку - ці функції формують масив байтів за стандартом UTF, який відповідає очікуваному тільки для ASCII-символів (перших 128 значень). Російські літери знову в прольоті. Сішние рядка char * дуже добре лягають на Java-івський тип byte [], але при цьому виникає заковика у вигляді нуль-символу. Його потрібно додавати при перетворенні byte [] -> char * і враховувати при зворотному перетворенні. Приклад: p> public void action (String msg) throws java.io.IOException
{
int res = nAction (msg);
if (res! = 0) throw new java.io.IOException ( nGetErrorString (res));
}
private native int nAction (String msg);
private native String nGetErrorString (int error);
...
jbyteArray getStringBytes (JNIEnv * Env, jstring str)
{
if (! str) return NULL;
jmethodID getBytes = env-> GetMethodID (env-> GetObjectClass (str), "getBytes", "() [B");
jbyteArray buf = (JbyteArray) env-> CallObjectMethod (str, getBytes);
if (! buf) return NULL;
// Додаємо нуль-символ
jsize len = env-> GetArrayLength (buf);
jbyteArray nbuf = env-> NewByteArray (len +1);
if (len! = 0)
{p> jbyte * cbuf = env-> GetByteArrayElements (buf, NULL);
env-> SetByteArrayRegion (nbuf, 0, len, cbuf);
env-> ReleaseByteArrayElements (buf, cbuf, JNI_ABORT);
} p> env-> DeleteLocalRef (buf);
return nbuf;
}
JNIEXPORT jint JNICALL Java_Test_nAction
(JNIEnv * env, jobject obj, jstring msg)
{
jbyteArray bmsg = getStringBytes (env, msg);
if (! bmsg) return -1;
jbyte * cmsg = env-> GetByteArrayElements (bmsg, NULL);
printf (cmsg);
jint res = do_something (cmsg);
env-> ReleaseByteArrayElements (bmsg, cmsg, JNI_ABORT);
return res;
}
jstring newString (JNIEnv * env, jbyteArray jbuf, int len)
{
jclass stringClass = env-> FindClass ("java/lang/String");
if (! stringClass) return NULL;
jmethodID init = env-> GetMethodID (stringClass, "", "([BII) V");
if (! init) return NULL;
return (Jstring) env-> NewObject (stringClass, init, jbuf, 0, len);
}
jstring newString (JNIEnv * env, const char * buf)
{
if (! buf) return NULL;
В
int bufLen = strlen (buf);
if (bufLen == 0)
{p> return env-> NewString ((const jchar *) L "", 0);
} p> jbyteArray jbuf = env-> NewByteArray (bufLen);
if (! jbuf) return NULL;
env-> SetByteArrayRegion (jbuf, 0, bufLen, (jbyte *) buf);
jstring jstr = newString (env, jbuf, bufLen);
env-> DeleteLocalRef (jbuf);
return jstr;
}