ネイティブ ライブラリは、有効な名前を持つ loadLibrary によってロードできます。例では、libXXXX .so Linux ファミリの場合、hellolib.so の名前を libhello.so に変更する必要があります。ちなみに、私は Java を jni で開発しています。実装とネイティブ インターフェイス (.c または .cpp) を分離します。
static {
System.loadLibrary("hello"); // will load libhello.so
}
実装ヘッダー (HelloImpl.h):
#ifndef _HELLO_IMPL_H
#define _HELLO_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
void sayHello ();
#ifdef __cplusplus
}
#endif
#endif
HelloImpl.cpp:
#include "HelloImpl.h"
#include <iostream>
using namespace std;
void sayHello () {
cout << "Hello World!" << endl;
return;
}
Hello.c (c で jni をコンパイルすることを好みます):
#include <jni.h>
#include "Hello.h"
#include "HelloImpl.h"
JNIEXPORT void JNICALL Java_Hello_sayHello (JNIEnv *env, jobject obj) {
sayHello();
return;
}
最後に、いくつかの手順でそれらをコンパイルできます:
<オール>g++ -c -I"/opt/java/include"-I"/opt/java/include/linux" HelloImpl.cpp
- jni を .o でコンパイル
g++ -I"/opt/java/include"-I"/opt/java/include/linux" -o libhello.so -shared-Wl,-soname,hello.so Hello.c HelloImpl.o -static -lc
ステップ 2 では、g++ を使用してコンパイルします。これはとても重要です。 C と C++ を混在させる方法
コンパイル後、nm:で関数の名前を確認できます:
$ nm libhello.so |grep say
00000708 T Java_Hello_sayHello
00000784 t _GLOBAL__I_sayHello
00000718 T sayHello
T とマークされた Java_Hello_sayHello があります。これは、ネイティブ メソッド名と正確に一致する必要があります。すべてが大丈夫なら。実行できます:
$ java -Djava.library.path=. Hello
Hello World!
最後に私のコードが動作します。これは hello.java です
public class hello {
public native void sayHello(int length) ;
public static void main (String args[]) {
String str = "I am a good boy" ;
hello h = new hello () ;
h.sayHello (str.length() ) ;
}
static {
System.loadLibrary ( "hello" ) ;
}
}
次のようにコンパイルする必要があります:
$ javac hello.java
.h ファイルを作成するには、次のコマンドを実行する必要があります:
$ javah -jni hello
hello.h
です :
JNIEXPORT void JNICALL Java_hello_sayHello
(JNIEnv *, jobject, jint);
ここは hello.c
です :
#include<stdio.h>
#include<jni.h>
#include "hello.h"
JNIEXPORT void JNICALL Java_hello_sayHello
(JNIEnv *env, jobject object, jint len) {
printf ( "\nLength is %d", len ); }
これをコンパイルして共有ライブラリを作成するには、次のコマンドを実行する必要があります:
$ gcc -I/usr/lib/jvm/java-6-openjdk/include -o libhello.so -shared hello.c
最後にこれを実行してください:
$ java -Djava.library.path=. hello
これは、C++ シンボルが利用できないことを訴えます。私がいつも JNI のことをしていたとき、C++ ライブラリでのリンクに問題があり、いつも普通の古い C に固執していたことを覚えているようです
標準 C になるようにコードを変更した場合 (およびファイルの名前を変更した場合):
#include <jni.h>
#include "Hello.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_Hello_sayHello (JNIEnv *env, jobject obj) {
printf("Hello World");
return;
}
そしてコンパイルします
gcc -I/usr/lib/jvm/java-6-openjdk/include -o libhellolib.so -shared Hello.c
動作します
java -Djava.library.path=`pwd` Hello
Hello World