GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara mengkompilasi pustaka dinamis untuk aplikasi JNI di linux?

Pustaka asli dapat dimuat oleh loadLibrary dengan nama yang valid. Sebagai contoh, libXXXX .so untuk keluarga linux, hellolib.so Anda harus mengganti nama menjadi libhello.so. Ngomong-ngomong, saya mengembangkan java dengan jni, saya akan memisahkan implementasi dan antarmuka asli (.c atau .cpp).

static {
    System.loadLibrary("hello"); // will load libhello.so
}

Header implementasi(HelloImpl.h):

#ifndef _HELLO_IMPL_H
#define _HELLO_IMPL_H

#ifdef __cplusplus
        extern "C" {
#endif

        void sayHello ();

#ifdef __cplusplus
        }
#endif

#endif

HaloImpl.cpp:

#include "HelloImpl.h"
#include  <iostream>

using namespace std;

void sayHello () {
    cout << "Hello World!" << endl;
    return;
}

Hello.c (Saya lebih suka mengkompilasi jni di c):

#include <jni.h>
#include "Hello.h"
#include "HelloImpl.h"

JNIEXPORT void JNICALL Java_Hello_sayHello (JNIEnv *env, jobject obj) {
    sayHello();
    return;
}

Terakhir, kita dapat mengompilasinya dalam beberapa langkah:

  1. kompilasi obj (hasilkan HelloImpl.o)

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

  1. kompilasi jni dengan .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

pada langkah 2, kami menggunakan g++ untuk mengompilasinya. Ini sangat penting. Anda dapat melihat Cara mencampur C dan C++

Setelah kompilasi, Anda dapat memeriksa penamaan fungsi dengan nm:

$ nm libhello.so |grep say
00000708 T Java_Hello_sayHello
00000784 t _GLOBAL__I_sayHello
00000718 T sayHello

Ada Java_Hello_sayHello bertanda T. Seharusnya persis sama dengan nama metode asli Anda. Jika semuanya baik-baik saja. Anda dapat menjalankannya:

$ java -Djava.library.path=. Hello
Hello World!

Akhirnya kode saya berfungsi. Ini adalah 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" ) ;
  }
}

Anda harus mengkompilasinya sebagai :

$ javac hello.java 

Untuk membuat file .h Anda harus menjalankan perintah ini:

$ javah -jni hello

Ini adalah hello.h :

JNIEXPORT void JNICALL Java_hello_sayHello
(JNIEnv *, jobject, jint);

Ini 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 ); }

Untuk mengkompilasi ini dan membuat perpustakaan bersama kita harus menjalankan perintah ini :

$ gcc -I/usr/lib/jvm/java-6-openjdk/include -o libhello.so -shared hello.c

Lalu akhirnya jalankan yang ini :

$ java -Djava.library.path=. hello

Ini mengeluh tentang simbol C++ yang tidak tersedia. Sepertinya saya ingat, ketika saya menggunakan untuk melakukan hal-hal JNI sepanjang waktu ada masalah penautan di pustaka C++ dan kami selalu terjebak pada C

lama biasa

Jika Anda mengubah kode Anda menjadi C standar (dan mengganti nama file):

#include <jni.h>
#include "Hello.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_Hello_sayHello (JNIEnv *env, jobject obj) {
        printf("Hello World");
        return;
}

Dan kompilasi

gcc -I/usr/lib/jvm/java-6-openjdk/include  -o libhellolib.so -shared Hello.c

Berhasil

java -Djava.library.path=`pwd` Hello
Hello World

Linux
  1. Linux – Bagaimana Mono Ajaib?

  2. Bagaimana Cara Menemukan Aplikasi Untuk Tipe Mime Di Linux?

  3. C++ Dynamic Shared Library di Linux

  1. Cara mengemas aplikasi Python untuk Linux

  2. Bagaimana cara membuat versi perpustakaan bersama di Linux?

  3. Cara mengatur googleTest sebagai perpustakaan bersama di Linux

  1. Bagaimana menangani perpustakaan dinamis dan statis di Linux

  2. Cara Memasang Pustaka Ncurses Di Linux

  3. Cara menginstal aplikasi Spotify di Linux