我正在尝试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 回答
您是否尝试在包含
stdio.h
和/或string.h
之后编译C文件?strupr不是标准ANSI C.如果您编写引用strupr的本机C应用程序,您将收到类似于您所看到的链接错误
解决方案是编写自己的strupr例程 .
Java似乎与使用其他库的JNI库有问题 . 我目前有同样的问题,我想用glib创建一个JNI库 . Java不想知道glib函数,尽管编译和链接都很好 .
因此,如果您编写JNI库,则不能使用该代码中的任何其他库!
我也面临同样的情况,但我从代码中删除了
strupr
函数,即strupr(cap)=> cap,现在我能够执行,因为strupr不是标准的ANSIC,你不能在那里定义 .