В eclipse, в 64-битных окнах, я пытаюсь запустить JNI-пример, включая тестирование двух методов обработки аргумента in/out int. Программа запускается и выполняет sayHello(), но заканчивается со следующим исключением для modIntPtr():JNI UnsatisfiedLinkError ... несоответствие подписи?
Исключение из потока "main" java.lang.UnsatisfiedLinkError: com.aaa.bbb.ccc.HelloJNI.modIntPtr (I [ I), V на com.aaa.bbb.ccc.HelloJNI.modIntPtr (нативный метод) на com.aaa.bbb.ccc.HelloJNI.main (HelloJNI.java:18)
я дважды проверил библиотеку, он имеет modIntPtr внутри него. Значит, я думаю, что это проблема с подписью? В .cpp-файле modIntPtr имеет jint, jintArray и возвращает пустоту. Это (I [I) V. В файле .h подпись - это (I [I) V. В HelloJNI.java я называю это следующим образом: новый HelloJNI(). ModIntPtr (100, intptr); intptr - тип int []. Так что это (I [I) V.
Так что если .dll содержит метод modIntPtr, я уверен, что он в актуальном состоянии, я уверен, что программа связывается с правильным .dll, и это не проблема подписи, что еще может быть ?
BTW, если я прокомментирую вызов modIntPtr, modIntRef работает.
Спасибо за помощь!
HelloJNI.java:
package com.aaa.bbb.ccc;
public class HelloJNI {
static {
System.loadLibrary("com_aaa_bbb_ccc");
}
// A native method that receives nothing and returns void
private native void sayHello();
private native void modIntPtr(int delta, int[] intptr);
private native void modIntRef(int delta, IntRef intref);
public static void main(String[] args) {
int[] intptr = new int[1];
intptr[0]=42;
IntRef intref = new IntRef(24);
new HelloJNI().sayHello(); // invoke the native method
new HelloJNI().modIntPtr(100, intptr);
new HelloJNI().modIntRef(100, intref);
}
}
HelloJNI.cpp
#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"
void SayHello(void)
{
printf("Hello World!\n");
return;
}
void IntRefNative(int delta, int *intptr)
{
printf("delta = %d\n",delta);
printf("intptr = %d\n",*intptr);
*intptr += delta;
printf("After mod...\n");
printf("intptr = %d\n",*intptr);
return;
}
JNIEXPORT void JNICALL Java_com_aaa_bbb_ccc_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
SayHello();
return;
}
JNIEXPORT void JNICALL Java_com_aaa_bbb_ccc_HelloJNI_modIntPtr(JNIEnv *env, jobject thisObj, jint delta, jintArray intptr) {
jint *body = env->GetIntArrayElements(intptr, 0);
printf("delta = %d\n",delta);
printf("intptr = %d\n",intptr[0]);
body[0] += delta;
env->ReleaseIntArrayElements(intptr, body, 0);
printf("After mod...\n");
printf("intptr = %d\n",intptr[0]);
return;
}
JNIEXPORT void JNICALL Java_com_aaa_bbb_ccc_HelloJNI_modIntRef(JNIEnv *env, jobject thisObj, jint delta, jobject intref) {
jclass cls = env->GetObjectClass(intref);
jmethodID methodID = env->GetMethodID(cls, "getValue", "()I");
jint value = env->CallIntMethod(intref, methodID);
IntRefNative(delta, (int *)(&value));
methodID = env->GetMethodID(cls, "setValue", "(I)V");
env->CallVoidMethod(intref, methodID, value);
return;
}
HelloJNI.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_aaa_bbb_ccc_HelloJNI */
#ifndef _Included_com_aaa_bbb_ccc_HelloJNI
#define _Included_com_aaa_bbb_ccc_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_aaa_bbb_ccc_HelloJNI
* Method: sayHello
* Signature:()V
*/
JNIEXPORT void JNICALL Java_com_aaa_bbb_ccc_HelloJNI_sayHello
(JNIEnv *, jobject);
/*
* Class: com_aaa_bbb_ccc_HelloJNI
* Method: modIntPtr
* Signature: (I[I)V
*/
JNIEXPORT void JNICALL Java_com_aaa_bbb_ccc_HelloJNI_modIntPtr
(JNIEnv *, jobject, jint, jintArray);
/*
* Class: com_aaa_bbb_ccc_HelloJNI
* Method: modIntRef
* Signature: (ILcom/aaa/bbb/ccc/IntRef;)V
*/
JNIEXPORT void JNICALL Java_com_aaa_bbb_ccc_HelloJNI_modIntRef
(JNIEnv *, jobject, jint, jobject);
#ifdef __cplusplus
}
#endif
#endif
И я включу этот файл, а также для всех, кто пытается найти идеи для передачи in/out или изменяемого параметра int в java ... Я искал всюду для рабочего примера.
IntRef.java
package com.aaa.bbb.ccc;
public class IntRef {
private int value;
IntRef() {
value=0;
}
IntRef(int v) {
value = v;
}
/**
* Returns the integer value of this <code>IntRef</code>
*
* @return the value of the integer in native int form
*/
public int getValue() {
return value;
}
/**
* Sets the value.
*
* @param theValue The value to set
*/
public void setValue(int theValue) {
this.value = theValue;
}
}