java — JNI передает длинное значение нативному методу

Итак, как описано выше, я пытаюсь скопировать объект int в память вне кучи с помощью Unsafe. Вот моя основная функция:

public static void main(String[] args) throws Exception {
UnsafeHelper hlpr = new UnsafeHelper();

int original = 100;
long copyaddress = hlpr.shallowCopy(original);
System.out.println("COPIED TO ADDRESS: " + copyaddress);
int copy = (int) hlpr.fromAddress(copyaddress);

getCopiedObject(copyaddress);
}

он дает мне адрес начала скопированного объекта (copyaddress).

Далее я хочу передать этот адрес функции, определенной в агенте jni. Вот объявление нативной функции в классе Java:

private static native void getCopiedObject(long address);

Вот объявление функции в agent.h:

JNIEXPORT void JNICALL Java_main_Main_getCopiedObject(JNIEnv *, jlong);

И вот тут я попадаю в беду … Длинное значение, которое я получаю в функции C ++, отличается от того, которое я передаю в Java …

JNIEXPORT void JNICALL Java_main_Main_getCopiedObject(JNIEnv *env, jlong address){
...
unsigned long long a = address;
signed long long b = address;
printf("UNSIGNED LONG LONG %llu \n", a);
printf("SIGNED LONG LONG %lld \n", b);
...
}

В моем случае размер Java Long составляет 64 бита, поэтому я использую long long в моем коде c ++ … я пробовал и подписанные и неподписанные преобразования, но это никогда не работало …

Поэтому, когда я запускаю этот код, я получаю следующие выводы:

JAVA:
COPIED TO ADDRESS: 1487190592
AGENT:
UNSIGNED LONG LONG 37025744
SIGNED LONG LONG 37025744

Согласно выводу, я неправильно конвертирую jlong ​​в long …

Кто-нибудь знает, как получить правильный long long значение из jlong ?

1

Решение

Кажется, я понял, в чем проблема. Когда у вас есть static native В методе есть 2 дополнительных аргумента, помимо того, что есть в Java. Во-первых, это JNIEnv а второй jclass,

Я не знаю, как именно вы создали свой .h файл, но когда я использую:

javah -jni Main

Я получаю подпись:

JNIEXPORT void JNICALL Java_Main_passLong(JNIEnv *, jclass, jlong);

в .h файл. Если я использую его таким образом, он ведет себя как ожидалось. Поэтому мое решение было бы добавить jclass параметр перед jlong,

Если я удалю jclass Параметр, я вижу неправильное значение. Я предполагаю, что JVM не проверяет подпись нативного метода при загрузке библиотеки.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]