Добрый день, подскажите как правильно вызвать из C++ следующий java метод:
Java:
public static void callBack( char data[], int length )
{
System.out.println( data );
System.out.println( length );
}
Пытаюсь так:
C++:
{
….
char *data = new char[3];
data[0] = '0';
data[1] = '1';
data[2] = '2';
int length =3;
env->CallStaticVoidMethod( jcClass, methodID, "([CI)V", data, length);
delete data;
}
И всё это дело весело рушиться с EXCEPTION_ACCESS_VIOLATION при System.out.println(data);
Что я делаю не так?
Здравствуйте, Аноним, Вы писали:
А>Пытаюсь так:
А>C++:
А>А>{
А>….
А>char *data = new char[3];
А>data[0] = '0';
А>data[1] = '1';
А>data[2] = '2';
А>int length =3;
env->>CallStaticVoidMethod( jcClass, methodID, "([CI)V", data, length);
А>delete data;
А>}
А>
А>И всё это дело весело рушиться с EXCEPTION_ACCESS_VIOLATION при System.out.println(data);
А>Что я делаю не так?
1) char в Java это далеко не char в С.
2) тебе нужно сделать NewCharArray() и его передать в Java функцию.
Здравствуйте, c-smile, Вы писали:
CS>1) char в Java это далеко не char в С.
CS>2) тебе нужно сделать NewCharArray() и его передать в Java функцию.
Понял. Теперь делаю так:
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 — т.е параметр не инициализируется ?). Вроде написано правильно?
Здравствуйте, Аноним, Вы писали:
А>...
А>Понял. Теперь делаю так:
А>А>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
Здравствуйте, bolshik, Вы писали:
B>Неправильно:
B>1. Memory leak, т.к. не возвращается память, выделенная в результате
delete вызывается ниже по коду (весь код не стал приводить).
B>2. Следующий вызов просто стреляет по памяти. Его результат непредсказуем, потому что DeleteLocalRef() вообще можно не вызывать, а если уж и дергать, то только для локальных ссылок (подробнее почитать об этом можно здесь)
Спасибо, просто сначала не понял...
B>Следующий код работает:
Спасибо, действительно теперь всё работает.
Здравствуйте, bolshik, Вы писали:
А где бы почитать про
([CI)V? Т.е. про третий параметр GetStaticMethodID... На каком основании эти кракозябры набираются?
jmethodID targetMethodId = env->GetStaticMethodID(clazz, "callback", "([CI)V");