2013-05-17 2 views
2

В 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; 
    } 
} 

ответ

0

код, как вывешенные работает без проблем. Я бы попытался сделать чистую сборку DLL; JVM должен загружать устаревшую версию откуда-то.

Кстати, там, кажется, ошибка в Java_com_aaa_bbb_ccc_HelloJNI_modIntPtr:

printf("intptr = %d\n",intptr[0]); 

, вероятно, должно быть:

printf("intptr = %d\n",body[0]);