GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie kompiliere ich eine dynamische Bibliothek für eine JNI-Anwendung unter Linux?

Native Bibliothek kann von loadLibrary mit einem gültigen Namen geladen werden. Zum Beispiel libXXXX .so für die Linux-Familie sollte Ihre hellolib.so in libhello.so umbenannt werden. Übrigens entwickle ich Java mit jni, ich werde die Implementierung und die native Schnittstelle (.c oder .cpp) trennen.

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

Der Implementierungsheader (HelloImpl.h):

#ifndef _HELLO_IMPL_H
#define _HELLO_IMPL_H

#ifdef __cplusplus
        extern "C" {
#endif

        void sayHello ();

#ifdef __cplusplus
        }
#endif

#endif

HalloImpl.cpp:

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

using namespace std;

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

Hello.c (ich bevorzuge es, jni in c zu kompilieren):

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

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

Schließlich können wir sie in einigen Schritten kompilieren:

  1. obj kompilieren (HelloImpl.o generieren)

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

  1. jni mit .o kompilieren

g++ -I"/opt/java/include"-I"/opt/java/include/linux" -o libhello.so -shared-Wl,-soname,hello.so Hello.c HelloImpl.o -static -lc

In Schritt 2 verwenden wir g++, um es zu kompilieren. Dies ist sehr wichtig. Sie können sehen, wie man C und C++ mischt

Nach dem Kompilieren können Sie die Funktionsbenennung mit nm:

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

Es gibt ein Java_Hello_sayHello, das mit T gekennzeichnet ist. Es sollte genau dem Namen Ihrer nativen Methode entsprechen. Ob alles in Ordnung ist. Sie können es ausführen:

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

Endlich funktioniert mein Code. Das ist 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" ) ;
  }
}

Sie sollten es als :

kompilieren
$ javac hello.java 

Um eine .h-Datei zu erstellen, sollten Sie diesen Befehl ausführen:

$ javah -jni hello

Das ist hello.h :

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

Hier ist 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 ); }

Um dies zu kompilieren und eine gemeinsam genutzte Bibliothek zu erstellen, müssen wir diesen Befehl ausführen:

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

Dann endlich dieses ausführen:

$ java -Djava.library.path=. hello

Dieser beschwert sich darüber, dass die C++-Symbole nicht verfügbar sind. Ich meine mich zu erinnern, dass es, als ich die ganze Zeit JNI-Zeug gemacht habe, Probleme beim Linken in C++-Bibliotheken gab und wir immer beim einfachen alten C

geblieben sind

Wenn Sie Ihren Code so ändern, dass er Standard-C ist (und die Datei umbenennen):

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

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

Und kompilieren Sie es

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

Es funktioniert

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

Linux
  1. So packen Sie Python-Anwendungen für Linux

  2. So installieren Sie die Ncurses-Bibliothek unter Linux

  3. So installieren Sie die Spotify-Anwendung unter Linux

  4. Linux – Wie ist Mono magisch?

  5. C++ Dynamic Shared Library unter Linux

So konfigurieren Sie Openbox für Ihren Linux-Desktop

So prüfen (scannen) Sie offene Ports in Linux

So richten Sie einen Pacemaker-Cluster für Linux mit hoher Verfügbarkeit ein

So installieren Sie die PyBrain-Python-Bibliothek unter Linux

So installieren Sie Setuptools für Python unter Linux

So kompilieren Sie die .NET Core-App für Linux auf einem Windows-Computer