Приведение типа C ++ long к JNI jlong - PullRequest
10 голосов
/ 24 сентября 2011

Я использую JNI для передачи данных между C ++ и Java.Мне нужно передать тип 'long', и я делаю это, используя что-то вроде:

 long myLongVal = 100;
 jlong val = (jlong)myLongVal;
 CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val);

Однако в Java, когда извлекается параметр 'long', он получается как очень большое отрицательное число.Что я делаю неправильно?

Ответы [ 2 ]

12 голосов
/ 24 сентября 2011

Когда вы передаете jlong ​​(который является 64-битным) в качестве указателя (который, скорее всего, 32-битный), вы обязательно потеряете данные. Я не уверен, что такое соглашение, но попробуйте либо это:

CallStaticVoidMethodA(myClass, "(J)V", (jvalue*)&val); //Note address-of!

или это:

CallStaticVoidMethod(myClass, "(J)V", val); 

Это ...A методы, которые принимают массив jvalue, методы без постфикса принимают эквиваленты C для скалярных типов Java.

Первый фрагмент кода несколько небезопасен; лучше, если более многословно, альтернатива будет:

jvalue jv;
jv.j = val;
CallStaticVoidMethodA(myClass, "(J)V", &jv);

В некоторых экзотических архитектурах ЦП требования к выравниванию переменных jlong и объединений jvalue могут отличаться. Когда вы объявляете объединение явно, об этом позаботится компилятор.

Также обратите внимание, что тип данных C ++ long часто является 32-разрядным. jlong ​​- 64 бита, на 32-битных платформах нестандартный эквивалент C равен long long или __int64.

3 голосов
/ 24 сентября 2011
CallStaticVoidMethod(myClass, "(J)V", (jvalue*)val);

Это неопределенное поведение.Вы приводите целое число, чтобы быть указателем.Это не указатель.Вам нужно, по крайней мере, передать адрес .Этот код на большинстве платформ мгновенно зависнет.

...