我正在尝试JNI示例代码 (您可以通过github获取以下所有来源:https://github.com/pilhoon/jni-test)
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); } }
#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
/* 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
我该如何解决这个问题?
答案 0 :(得分:2)
您是否尝试在加入stdio.h
和/或string.h
之后编译C文件?
答案 1 :(得分:2)
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 :(得分:-1)
Java似乎在使用其他库的JNI库时遇到问题。 我目前有同样的问题,我想用glib创建一个JNI库。 Java不想知道glib函数,尽管编译和链接都很好。
因此,如果您编写JNI库,则不能使用该代码中的任何其他库!
编辑:将所有库静态链接到您的JNI库中。这应该有效!
答案 3 :(得分:-1)
我也面临同样的情况,但我从代码中移除了strupr
函数,即strupr(cap)=&gt; cap,现在我能够执行,因为strupr不是标准的ANSIC,你不能在那里定义。