2013-10-15 60 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,所以不能在那里定义。