jni未定义的符号错误

我正在尝试JNI示例代码 .
(您可以通过github获取以下所有来源:https://github.com/pilhoon/jni-test

  • 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上用gcc编译了这些

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

但是当我运行'java Sample'时,会发生错误 .

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

我怎样才能解决这个问题?

回答(4)

2 years ago

您是否尝试在包含 stdio.h 和/或 string.h 之后编译C文件?

2 years ago

strupr不是标准ANSI C.如果您编写引用strupr的本机C应用程序,您将收到类似于您所看到的链接错误

$ 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例程 .

2 years ago

Java似乎与使用其他库的JNI库有问题 . 我目前有同样的问题,我想用glib创建一个JNI库 . Java不想知道glib函数,尽管编译和链接都很好 .

因此,如果您编写JNI库,则不能使用该代码中的任何其他库!

2 years ago

我也面临同样的情况,但我从代码中删除了 strupr 函数,即strupr(cap)=> cap,现在我能够执行,因为strupr不是标准的ANSIC,你不能在那里定义 .