Re[3]: Jni: вызов java метода из native кода
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 12.03.07 13:08
Оценка:
Здравствуйте, Аноним, Вы писали:

А>...


А>Понял. Теперь делаю так:

А>
А>jchar *data = new jchar[3];
А>data[0] = '1';
А>data[1] = '2';
А>data[2] = '3';
А>jcharArray jdata = env->NewCharArray( 3 );    
env->>SetCharArrayRegion( jdata, 0, 3, data );
А>jint t =3;
env->>CallStaticVoidMethod( javaClass, methodID, "([CI)V", jdata, t );
env->>DeleteLocalRef( jdata );
А>

А>Опять получаю EXCEPTION_ACCESS_VIOLATION. Самое интересное то, что переменная t (=3) тоже не передаётся ( выводится 44192356 — т.е параметр не инициализируется ?). Вроде написано правильно?

Неправильно:

1. Memory leak, т.к. не возвращается память, выделенная в результате

jchar *data = new jchar[3];


2. Следующий вызов просто стреляет по памяти. Его результат непредсказуем, потому что DeleteLocalRef() вообще можно не вызывать, а если уж и дергать, то только для локальных ссылок (подробнее почитать об этом можно здесь)

env->DeleteLocalRef( jdata );


Следующий код работает:

Java:


public class BBB {

    static {
        System.loadLibrary("./res/test");
    }

    public static void main(String[] args) throws Exception {
        callNative();
    }

    public static void callback(char data[], int length) {
        System.out.println(data);
        System.out.println("length = " + length);
    }

    private static native void callNative();
}


Cpp

#include "jni.h"

template<int N>
jint getArraySize(jchar (&array)[N]) {
    return (jint)(sizeof(array) / sizeof(array[0]));
}

#ifndef _Included_BBB
#define _Included_BBB
#ifdef __cplusplus
extern "C" {
#endif
    /*
    * Class:     BBB
    * Method:    callNative
    * Signature: ()V
    */
    JNIEXPORT void JNICALL Java_BBB_callNative(JNIEnv* env, jclass clazz) {
        jcharArray array = env->NewCharArray(2);
        jchar buffer[] = {'A', 'B'};
        env->SetCharArrayRegion(array, 0, getArraySize(buffer), (jchar*)buffer);
        jmethodID targetMethodId = env->GetStaticMethodID(clazz, "callback", "([CI)V");
        env->CallStaticVoidMethod(clazz, targetMethodId, array, getArraySize(buffer));
    }

#ifdef __cplusplus
}
#endif
#endif
http://denis-zhdanov.blogspot.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.