2013-05-17 42 views
2

在eclipse中,在64位窗口上,我試圖獲得一個JNI示例,包括嘗試兩種處理輸入/輸出int參數的方法。該程序運行並執行sayHello(),但以modIntPtr()的以下異常終止:JNI UnsatisfiedLinkError ...簽名差異?

線程「main」中的異常java.lang.UnsatisfiedLinkError:com.aaa.bbb.ccc.HelloJNI.modIntPtr(I [我)V 在com.aaa.bbb.ccc.HelloJNI.modIntPtr(本機方法) 在com.aaa.bbb.ccc.HelloJNI.main(HelloJNI.java:18)

我雙重檢查庫,它的確有modIntPtr。所以我認爲這一定是一個簽名問題?在.cpp文件中,modIntPtr有一個jint,jintArray,並返回一個void。那是(I [I] V。在.h文件中,簽名是(I [I)V。在HelloJNI.java中,我這樣調用它: new HelloJNI()。modIntPtr(100,intptr); intptr是類型int []。那也是(I [I] V)。

因此,如果.dll包含modIntPtr方法,我相信它是最新的,我確信該程序與正確的.dll鏈接,這不是一個簽名問題,還有什麼可以?

順便說一句,如果我註釋掉對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 

我會包括這個文件,以及任何人誰是試圖找到在java中傳入輸入/輸出或可變int參數的想法......我到處搜索了一個工作示例。
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]);