GNU/Linux >> Linux の 問題 >  >> Linux

LinuxでJNIアプリケーションの動的ライブラリをコンパイルするには?

ネイティブ ライブラリは、有効な名前を持つ 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;
}

最後に、いくつかの手順でそれらをコンパイルできます:

<オール>
  • obj をコンパイル (HelloImpl.o を生成)
  • <ブロック引用>

    g++ -c -I"/opt/java/include"-I"/opt/java/include/linux" HelloImpl.cpp

    1. 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
    

    Linux
    1. Linux用のPythonアプリケーションをパッケージ化する方法

    2. LinuxにNcursesライブラリをインストールする方法

    3. Linux –モノマジカルはどうですか?

    1. LinuxでMimeタイプのアプリケーションを見つける方法は?

    2. Linux 上の C++ 動的共有ライブラリ

    3. Linux で googleTest を共有ライブラリとして設定する方法

    1. Linuxで動的ライブラリと静的ライブラリを処理する方法

    2. LinuxにSpotifyアプリケーションをインストールする方法

    3. Cobol Hello World の例:Linux OS で Cobol プログラムを作成、コンパイル、実行する方法