2

JNIサンプルコードを試しています。
(以下のソースはすべて github から入手できます: https://github.com/pilhoon/jni-test )

  • サンプル.java
public クラス サンプル
{
  パブリック ネイティブ 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("サンプル");
    サンプル サンプル = 新しいサンプル();
    int スクエア = 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: " + テキスト);
    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) {
   数値 * 数値を返します。
}

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(キャップ、str);
    (*env)->ReleaseStringUTFChars(env, string, str);
    return (*env)->NewStringUTF(env, strupr(cap));
}

JNIEXPORT jint JNICALL Java_Sample_intArrayMethod
  (JNIEnv *env, jobject obj, jintArray 配列) {
    int 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
}
#endif

  • サンプル.h
/* このファイルは編集しないでください - これは機械で生成されたものです */
#include <jni.h>
/* Sample クラスのヘッダー */

#ifndef _Included_Sample
#define _Included_Sample
#ifdef __cplusplus
extern "C" {
#endif
/*
 * クラス: サンプル
 * メソッド: int メソッド
 * 署名: (I)I
 */
JNIEXPORT jint JNICALL Java_Sample_intMethod
  (JNIEnv *、jobject、ジント);

/*
 * クラス: サンプル
 * メソッド: booleanMethod
 * 署名: (Z)Z
 */
JNIEXPORT jboolean JNICALL Java_Sample_booleanMethod
  (JNIEnv *、jobject、jboolean);

/*
 * クラス: サンプル
 * メソッド: stringMethod
 * 署名: (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
}
#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 サンプル」を実行すると、エラーが発生します。

java: シンボル検索エラー: /home/ph/tmp/jni/libsample.so: 未定義のシンボル: strupr

どうすればこれを修正できますか?

4

3 に答える 3

2

stdio.hand/orをインクルードした後に 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 に答える