GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo compilar una biblioteca dinámica para una aplicación JNI en Linux?

La biblioteca nativa se puede cargar mediante loadLibrary con un nombre válido. Por ejemplo, libXXXX .so para la familia linux, su hellolib.so debería cambiar el nombre a libhello.so. Por cierto, desarrollo java con jni, separaré la implementación y la interfaz nativa (.c o .cpp).

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

El encabezado de implementación (HelloImpl.h):

#ifndef _HELLO_IMPL_H
#define _HELLO_IMPL_H

#ifdef __cplusplus
        extern "C" {
#endif

        void sayHello ();

#ifdef __cplusplus
        }
#endif

#endif

HolaImpl.cpp:

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

using namespace std;

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

Hola.c (prefiero compilar jni en c):

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

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

Finalmente, podemos compilarlos en algunos pasos:

  1. compilar obj (generar HelloImpl.o)

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

  1. compilar jni con .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

en el paso 2, usamos g++ para compilarlo. Esto es muy importante. Puedes ver Cómo mezclar C y C++

Después de la compilación, puede verificar el nombre de la función con nm:

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

Hay un Java_Hello_sayHello marcado como T. Debería ser exactamente igual al nombre de su método nativo. Si todo esta bien. puedes ejecutarlo:

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

Finalmente mi código funciona. Esto es 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" ) ;
  }
}

Deberías compilarlo como:

$ javac hello.java 

Para crear un archivo .h, debe ejecutar este comando:

$ javah -jni hello

Este es hello.h :

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

Aquí está 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 ); }

Para compilar esto y crear una biblioteca compartida, debemos ejecutar este comando:

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

Entonces finalmente ejecute este:

$ java -Djava.library.path=. hello

Esto se queja de que los símbolos de C++ no están disponibles. Me parece recordar, cuando solía hacer cosas de JNI todo el tiempo, había problemas para vincular en las bibliotecas de C ++ y siempre nos limitamos a C simple y antiguo

Si cambia su código para que sea C estándar (y cambia el nombre del archivo):

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

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

Y compilarlo

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

Funciona

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

Linux
  1. Cómo manejar bibliotecas dinámicas y estáticas en Linux

  2. Cómo empaquetar aplicaciones de Python para Linux

  3. Cómo instalar la biblioteca Ncurses en Linux

  4. Biblioteca compartida dinámica de C++ en Linux

  5. ¿Cómo hacer el control de versiones de una biblioteca compartida en Linux?

Cómo configurar Openbox para tu escritorio Linux

Cómo comprobar (escanear) los puertos abiertos en Linux

Cómo configurar un clúster de Pacemaker para Linux de alta disponibilidad

Cómo instalar la biblioteca Python de PyBrain en Linux

Cómo instalar Setuptools para Python en Linux

Cómo compilar la aplicación .NET Core para Linux en una máquina con Windows