GNU/Linux >> Tutoriels Linux >  >> Linux

Comment compiler une bibliothèque dynamique pour une application JNI sous Linux ?

La bibliothèque native peut être chargée par loadLibrary avec un nom valide. Par exemple, libXXXX .so pour la famille linux, votre hellolib.so devrait se renommer en libhello.so. Au fait, je développe java avec jni, je vais séparer l'implémentation et l'interface native (.c ou .cpp).

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

L'en-tête d'implémentation (HelloImpl.h):

#ifndef _HELLO_IMPL_H
#define _HELLO_IMPL_H

#ifdef __cplusplus
        extern "C" {
#endif

        void sayHello ();

#ifdef __cplusplus
        }
#endif

#endif

BonjourImpl.cpp :

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

using namespace std;

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

Hello.c (je préfère compiler jni en c) :

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

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

Enfin, nous pouvons les compiler en quelques étapes :

  1. compiler obj (générer HelloImpl.o)

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

  1. compiler jni avec .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

à l'étape 2, nous utilisons g++ pour le compiler. C'est très important. vous pouvez voir comment mélanger C et C++

Après compilation, vous pouvez vérifier le nommage de la fonction avec nm :

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

Il existe un Java_Hello_sayHello marqué T. Il doit être exactement égal au nom de votre méthode native. Si tout va bien. vous pouvez l'exécuter :

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

Enfin mon code fonctionne. C'est 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" ) ;
  }
}

Vous devriez le compiler comme :

$ javac hello.java 

Pour créer un fichier .h, vous devez exécuter cette commande :

$ javah -jni hello

C'est hello.h :

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

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

Pour compiler cela et créer une bibliothèque partagée, nous devons exécuter cette commande :

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

Puis lancez enfin celui-ci :

$ java -Djava.library.path=. hello

Cela se plaint que les symboles C++ ne sont pas disponibles. Il me semble me souvenir, quand j'avais l'habitude de faire des trucs JNI tout le temps qu'il y avait des problèmes de liaison dans les bibliothèques C++ et que nous nous en tenions toujours au bon vieux C

Si vous modifiez votre code pour qu'il soit en C standard (et renommez le fichier) :

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

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

Et compilez-le

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

Ça marche

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

Linux
  1. Comment trouver l'application pour un type MIME sous Linux ?

  2. Exemple Cobol Hello World :comment écrire, compiler et exécuter un programme Cobol sur un système d'exploitation Linux

  3. Exemple Tcl Hello World :comment écrire, compiler et exécuter un programme Tcl sur un système d'exploitation Linux

  4. Bibliothèque partagée dynamique C++ sous Linux

  5. Comment faire le versioning d'une bibliothèque partagée sous Linux ?

Comment configurer Openbox pour votre bureau Linux

Comment vérifier (scanner) les ports ouverts sous Linux

Comment configurer un cluster Pacemaker pour Linux haute disponibilité

Comment installer la bibliothèque Python PyBrain sous Linux

Comment installer Setuptools pour Python sur Linux

Comment compiler l'application .NET Core pour Linux sur une machine Windows