2

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

  • 示例.java
公共课示例
{
  公共本机 int intMethod(int n);
  public native boolean booleanMethod(boolean bool);
  public native String stringMethod(String text);
  公共本机 int intArrayMethod(int[] intArray);

  公共静态无效主要(字符串 [] 参数)
  {
    System.loadLibrary("样本");
    样品样品 = 新样品();
    int square = sample.intMethod(5);
    boolean bool = sample.booleanMethod(true);
    字符串文本 = 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);
  }
}
  • 样本.c
#include "sample.h"
#include <string.h>

#ifdef __cplusplus
外部“C”{
#万一

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

JNIEXPORT jboolean JNICALL Java_Sample_booleanMethod
  (JNIEnv *env, jobject obj, jboolean boolean) {
  返回!布尔值;
}

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

JNIEXPORT jint JNICALL Java_Sample_intArrayMethod
  (JNIEnv *env, jobject obj, jintArray 数组) {
    整数 i, 总和 = 0;
    jsize len = (*env)->GetArrayLength(env, array);
    jint *body = (*env)->GetIntArrayElements(env, array, 0);
    for (i=0; iReleaseIntArrayElements(env, array, body, 0);
    返回总和;
}

无效的主要(){}

#ifdef __cplusplus
}
#万一

  • 样本.h
/* 不要编辑这个文件 - 它是机器生成的 */
#include <jni.h>
/* 类示例的标题 */

#ifndef _Included_Sample
#define _Included_Sample
#ifdef __cplusplus
外部“C”{
#万一
/*
 * 类别:样本
 * 方法:intMethod
 * 签名:(I)I
 */
JNIEXPORT jint JNICALL Java_Sample_intMethod
  (JNIEnv *, jobject, jint);

/*
 * 类别:样本
 * 方法:布尔方法
 * 签名:(Z)Z
 */
JNIEXPORT jboolean JNICALL Java_Sample_booleanMethod
  (JNIEnv *, jobject, jboolean);

/*
 * 类别:样本
 * 方法:字符串方法
 * 签名:(Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_Sample_stringMethod
  (JNIEnv *, jobject, jstring);

/*
 * 类别:样本
 * 方法:intArrayMethod
 * 签名:([I)I
 */
JNIEXPORT jint JNICALL Java_Sample_intArrayMethod
  (JNIEnv *, jobject, jintArray);

#ifdef __cplusplus
}
#万一
#万一

我在 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:符号查找错误:/home/ph/tmp/jni/libsample.so:未定义符号:strupr

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

4

3 回答 3

2

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

于 2013-10-15T05:15:21.147 回答
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 例程。

于 2013-10-15T14:58:00.130 回答
-1

Java 似乎对使用其他库的 JNI 库有问题。我现在有同样的问题,我想使用 glib 制作一个 JNI 库。Java 不想知道 glib 函数,尽管一切编译和链接都很好。

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

编辑:将任何库静态链接到您的 JNI 库中。那应该工作!

于 2014-03-07T21:50:43.830 回答