2013-10-15 80 views
1

我在嘗試JNI示例代碼。
(你可以得到以下的所有來源,通過github上:https://github.com/pilhoon/jni-testjni未定義符號錯誤

  • Sample.java
 
public class Sample 
{ 
    public native int intMethod(int n); 
    public native boolean booleanMethod(boolean bool); 
    public native String stringMethod(String text); 
    public native int intArrayMethod(int[] intArray); 

    public static void main(String[] args) 
    { 
    System.loadLibrary("sample"); 
    Sample sample = new Sample(); 
    int  square = sample.intMethod(5); 
    boolean bool = sample.booleanMethod(true); 
    String text = sample.stringMethod("JAVA"); 
    int  sum = sample.intArrayMethod(new int[]{1,1,2,3,5,8,13}); 

    System.out.println("intMethod: " + square); 
    System.out.println("booleanMethod: " + bool); 
    System.out.println("stringMethod: " + text); 
    System.out.println("intArrayMethod: " + sum); 
    } 
} 
  • sample.c文件
 
#include "sample.h" 
#include <string.h> 

#ifdef __cplusplus 
extern "C" { 
#endif 

JNIEXPORT jint JNICALL Java_Sample_intMethod 
    (JNIEnv *env, jobject obj, jint num) { 
    return num * num; 
} 

JNIEXPORT jboolean JNICALL Java_Sample_booleanMethod 
    (JNIEnv *env, jobject obj, jboolean boolean) { 
    return !boolean; 
} 

JNIEXPORT jstring JNICALL Java_Sample_stringMethod 
    (JNIEnv *env, jobject obj, jstring string) { 
    const char *str = (*env)->GetStringUTFChars(env, string, 0); 
    char cap[128]; 
    strcpy(cap, str); 
    (*env)->ReleaseStringUTFChars(env, string, str); 
    return (*env)->NewStringUTF(env, strupr(cap)); 
} 

JNIEXPORT jint JNICALL Java_Sample_intArrayMethod 
    (JNIEnv *env, jobject obj, jintArray array) { 
    int i, sum = 0; 
    jsize len = (*env)->GetArrayLength(env, array); 
    jint *body = (*env)->GetIntArrayElements(env, array, 0); 
    for (i=0; iReleaseIntArrayElements(env, array, body, 0); 
    return sum; 
} 

void main(){} 

#ifdef __cplusplus 
} 
#endif 

  • sample.h
 
/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h> 
/* Header for class Sample */ 

#ifndef _Included_Sample 
#define _Included_Sample 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  Sample 
* Method: intMethod 
* Signature: (I)I 
*/ 
JNIEXPORT jint JNICALL Java_Sample_intMethod 
    (JNIEnv *, jobject, jint); 

/* 
* Class:  Sample 
* Method: booleanMethod 
* Signature: (Z)Z 
*/ 
JNIEXPORT jboolean JNICALL Java_Sample_booleanMethod 
    (JNIEnv *, jobject, jboolean); 

/* 
* Class:  Sample 
* Method: stringMethod 
* Signature: (Ljava/lang/String;)Ljava/lang/String; 
*/ 
JNIEXPORT jstring JNICALL Java_Sample_stringMethod 
    (JNIEnv *, jobject, jstring); 

/* 
* Class:  Sample 
* Method: intArrayMethod 
* Signature: ([I)I 
*/ 
JNIEXPORT jint JNICALL Java_Sample_intArrayMethod 
    (JNIEnv *, jobject, jintArray); 

#ifdef __cplusplus 
} 
#endif 
#endif 

我在CentOS 6.3

 
prompt$ gcc -c -o sample.o -fPIC sample.c -I /usr/java/jdk1.7.0_07/include/ -I /usr/java/jdk1.7.0_07/include/linux/ 
prompt$ gcc -shared -o libsample.so sample.o 

編譯這些用gcc但是當我運行的Java樣',出現錯誤。

 
java: symbol lookup error: /home/ph/tmp/jni/libsample.so: undefined symbol: strupr 

我該如何解決這個問題?

+0

好的,如果這個問題是由於非標準功能造成的,爲什麼不用jni運行呢?我認爲jni只提供接口,所以如果我可以在native-C或C++上運行一些代碼,它必須可以用jni。不是嗎? – plhn

回答

2

您是否在包含stdio.h和/或string.h後嘗試編譯C文件?

+1

抱歉,我只是糾正了我的問題。 ''被自動識別爲標籤並且不可見。 – plhn

+0

我唯一的想法是讓你嘗試在一行中編譯它,比如'gcc -fPIC $ CPPFLAGS -o libsample.so -shared sample.c',其中包含$ CPPFLAGS。 – bourbaki4481472

+0

謝謝你的建議,但它不起作用。 – plhn

2

strupr不標準ANSI C,如果你寫了一個原生的C程序引用strupr,你將你所看到

$ gcc -o sample -fPIC Sample.c -I /xxx/include/ -I /xxx/include/linux/ 
Sample.c: In function âJava_Sample_stringMethodâ: 
Sample.c:23: warning: passing argument 2 of â(*env)->NewStringUTFâ makes pointer from    integer without a cast 
Sample.c: In function âmainâ: 
Sample.c:40: warning: passing argument 1 of âprintfâ makes pointer from integer without a cast 
/tmp/cc6hPBKz.o: In function `Java_Sample_stringMethod': 
Sample.c:(.text+0xaa): undefined reference to `strupr' 
/tmp/cc6hPBKz.o: In function `main': 
Sample.c:(.text+0x103): undefined reference to `strupr' 
collect2: ld returned 1 exit status 

解決辦法是寫自己的strupr例行得到類似鏈接錯誤。

0

Java似乎對使用其他庫的JNI庫存在問題。 我現在有同樣的問題,我想用glib製作一個JNI庫。 Java不想知道glib的功能,儘管一切編譯和鏈接都很好。

所以,如果您編寫JNI庫,您不能使用該代碼中的任何其他庫!

-1

我也面臨同樣的情況,但我從代碼中刪除了strupr函數,即strupr(cap)=> cap,現在我可以執行了,因爲strupr不是標準ANSIC,所以不能在那裏定義。