C++ファイルから読み取るEclipseでプラグインを開発しています。C++ ファイルに const char * データがあり、Java に読み込む次のプログラムがありますが、Eclipse を使用して Java で文字列部分を読み取るときに例外アクセス違反エラーが発生しますが、long と整数では正常に動作します。誰が間違いを指摘できますか?
JNIEXPORT void JNICALL Java_otf_OtfJni_otfjni_1set_1handler
(JNIEnv *env, jobject obj, jint type, jobject handler, jstring signature)
{
struct callback *cb;
jclass handler_class = (*env)->GetObjectClass(env, handler);
cb = (struct callback *)malloc(sizeof(struct callback));
printf("adding a handler\n");
cb->env = env;
cb->handler = (*env)->NewGlobalRef(env, handler);
cb->id = (*env)->GetMethodID(env, handler_class, "handle", "([Ljava/lang/Object;)V");
cb->signature_ref = (*env)->NewGlobalRef(env, signature);
cb->signature = (*env)->GetStringUTFChars(env, signature, NULL);
printf("Signature is: %s\n", cb->signature);
OTF_HandlerArray_setHandler(handlers, testhandler, type);
OTF_HandlerArray_setFirstHandlerArg(handlers, (void *)cb, type);
}
static int testhandler(void *arg, ...)
{
int i;
struct callback *cb = (struct callback *)arg;
JNIEnv *env = cb->env;
char *sig = cb->signature;
jint size = (jint) strlen(sig);
jint size1;
va_list arguments;
jobjectArray return_array;
jclass obj_class;
jbyteArray bytes;
jstring str;
obj_class = (*env)->FindClass(env, "java/lang/Object");
return_array = (*env)->NewObjectArray(env, size, obj_class, NULL);
va_start(arguments, arg);
for (i = 0; i < size; i++) {
jclass clazz;
jmethodID id;
jobject obj;
jobject encoding;
switch (sig[i]) {
case 'i': {
clazz = (*env)->FindClass(env, "java/lang/Integer");
id = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
obj = (*env)->NewObject(env, clazz, id, va_arg(arguments, uint32_t));
(*env)->SetObjectArrayElement(env, return_array, i, obj);
break;
}
case 'l': {
clazz = (*env)->FindClass(env, "java/lang/Long");
id = (*env)->GetMethodID(env, clazz, "<init>", "(J)V");
obj = (*env)->NewObject(env, clazz, id, va_arg(arguments, uint64_t));
(*env)->SetObjectArrayElement(env, return_array, i, obj);
break;
}
case 's': {
clazz = (*env)->FindClass(env, "java/lang/String");
size1 = (jint) strlen(va_arg(arguments, char *));
id = (*env)->GetMethodID(env, clazz, "<init>", "([BLjava/lang/String;)V");
encoding = (*env)->NewStringUTF(env, va_arg(arguments, uint64_t));
bytes = (*env)->NewByteArray(env, size1);
(*env)->SetByteArrayRegion(env, bytes, 0, size1, (jbyte *)(va_arg(arguments, char *)));
str = (jstring)(*env)->NewObject(env, clazz, id , bytes);
obj = (*env)->NewObject(env, clazz, id, str);
(*env)->SetObjectArrayElement(env, return_array, i, obj);
break;
}
default: {
printf("unknown signature char '%c'\n", sig[i]);
}
}
}
va_end(arguments);
(*env)->CallVoidMethod(env, cb->handler, cb->id, return_array);
return 0;
}
Java では、テストハンドラーは次のように呼び出されます。
o.otfjni_set_handler(OtfJni.OTF_DEFFUNCTION_RECORD, newhandler, "iisii");
ここで、's' は C++ から読み取る文字列部分を表します。