Heim > Java > Hauptteil

Kompilierte C++-Bibliotheksfunktion nicht gefunden

WBOY
Freigeben: 2024-02-08 23:57:19
nach vorne
924 Leute haben es durchsucht

Beim Schreiben von C++-Programmen kann es beim PHP-Editor Youzi manchmal zu dem Problem kommen, dass „kompilierte C++-Bibliotheksfunktionen nicht gefunden werden können“. Dieser Fehler tritt normalerweise während der Verknüpfungsphase auf und bedeutet, dass der Compiler die erforderliche Bibliotheksfunktion nicht finden kann. Für dieses Problem kann es viele Gründe geben, z. B. eine falsche Konfiguration des Bibliotheksdateipfads, eine unsachgemäße Installation der Bibliotheksdatei usw. Um dieses Problem zu lösen, können wir es beheben, indem wir den Pfad der Bibliotheksdatei überprüfen, die Bibliotheksdatei neu installieren und den Compiler aktualisieren. In diesem Artikel erfahren Sie im Detail, wie Sie diesen häufigen Kompilierungsfehler beheben können.

Frageninhalt

Ich habe eine Datei namens libmylibrary.a und eine Header-Datei namens mylibrary.h die eine Funktion namens myfunction() enthält. Ich habe sie mit der CPP-Datei (helloworldjni.cpp) kombiniert und eine neue Bibliothek namens native.dll erstellt. Wenn ich jedoch versuche, native.dll in Java mit jni zu kompilieren, kann ich die Funktionen in libmylibrary.a und mylibrary.h nicht finden.

mylibrary.h

// mylibrary.h
#ifndef mylibrary_h
#define mylibrary_h

#ifdef __cplusplus
extern "c" {
#endif

void myfunction();  // declare the function prototype

#ifdef __cplusplus
}
#endif

#endif // mylibrary_h
Nach dem Login kopieren

Das sind die Schritte, die ich befolgt habe

1. Erstellen Sie eine Java-Datei (helloworldjni.java) zur Integration von jni

public class helloworldjni {
    static {
        system.load("/home/centos/test5/native.dll");
    }
    public static void main(string[] args) {
        new helloworldjni().sayhello();
    }
  //native method with no body
  public native void sayhello();
}
Nach dem Login kopieren

2. Verwenden Sie diesen Befehl, um die Datei helloworldjni.h zu erstellen

javac -h .  helloworldjni.java
Nach dem Login kopieren

3. Integrieren Sie die Dateien mylibrary.h und helloworldjni.h in meine CPP-Datei (helloworldjni.cpp)

#include<iostream>
#include<jni.h>
#include "mylibrary.h"
#include "helloworldjni.h"
void sayhello(){
  myfunction();
}
int main() {
    sayhello();  // call the function from the library

    return 0;
}
jniexport void jnicall java_helloworldjni_sayhello
  (jnienv* env, jobject thisobject) {
    sayhello();
}
Nach dem Login kopieren

4. Kompilieren Sie diese Dateien (erstellen Sie .o-Dateien)

g++ helloworldjni.cpp -l. -lmylibrary -i"/home/centos/jdk-21.0.1/include" -i"/home/centos/jdk-21.0.1/include/linux" -o helloworldjni.o
Nach dem Login kopieren

5. .o-Datei in .dll-Datei generieren

g++ -shared -o native.dll helloworldjni.o
Nach dem Login kopieren

6. Kompilieren Sie helloworldjni.java und führen Sie es aus

java helloworldjni
Nach dem Login kopieren

Diesen Fehler erhalten:

java: symbol lookup error: /home/centos/test5/native.dll: undefined symbol: myFunction
Nach dem Login kopieren

Wie integriere ich

libmylibrary.a in meine Java-Code-Kompilierung, um sicherzustellen, dass die Funktionen in libmylibrary.a erkannt werden?

ps: Ich bin mir sicher, dass an libmylibrary.a nichts auszusetzen ist, da ich myfunction() mit reinem C++ aufrufen kann, aber bei der Verwendung von jni scheint es ein Verknüpfungsproblem zu geben, das ich nicht herausfinden kann

Workaround

Ich habe alle Ihre Schritte ausprobiert und einige geringfügige Änderungen vorgenommen, und das hat bei mir funktioniert. Zusätzliches Build-Skript:

#!/bin/sh

JAVA_SDK_HOME=/home/user/lib/jdk-21.0.1

#echo BUILD THE LIB
#g++ -c mylibrary.cpp -o mylibrary.o
#ar rcs libmylibrary.a mylibrary.o

echo MAKE JAVA STUB
$JAVA_SDK_HOME/bin/javac -h . HelloWorldJNI.java

echo BUILD SO file
g++ -c -fPIC -o HelloWorldJNI.o HelloWorldJNI.cpp \
  -I $JAVA_SDK_HOME/include/ \
  -I $JAVA_SDK_HOME/include/linux

g++ -shared -o native.dll HelloWorldJNI.o -L. -lmylibrary

echo TESTING
$JAVA_SDK_HOME/bin/java HelloWorldJNI


Nach dem Login kopieren
Aber es gibt einige Einschränkungen:

    Unter Windows müssen Sie höchstwahrscheinlich einige Makros einrichten, also
  1. jniexport 实际上是 __declspec(dllexport),而不是 __declspec(dllimport)
  2. Zum Verlinken unter Linux
  3. C++-Dateien kompilieren*.so 文件,您需要使用 -fpic

Das obige ist der detaillierte Inhalt vonKompilierte C++-Bibliotheksfunktion nicht gefunden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage