1

我在 Eclipse 中开发了一个从 C++ 文件中读取的插件。我的 C++ 文件中有 const char * 数据,并且我有以下程序可以读入 Java,但是在使用 Eclipse 读取 Java 中的字符串部分时发生异常访问冲突错误,而它对于 long 和 integer 工作正常。谁能指出错误是什么?

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 中,testhandler 的调用方式如下:

o.otfjni_set_handler(OtfJni.OTF_DEFFUNCTION_RECORD, newhandler, "iisii");

其中 's' 代表要从 C++ 读取的字符串部分。

4

0 回答 0