Компиляция собственного кода JNI C ++ с помощью x86_64-w64-mingw32-g ++ - PullRequest
0 голосов
/ 25 июня 2018

Я хочу скомпилировать и запустить простую программу Hello World, которая объявляет и вызывает собственный метод печати (определенный в C ++) из Java.

HelloCPP.java

class HelloCPP{
    private native void print();
    public static void main(String [] args){
        new HelloCPP().print();
    }
    static{
        System.loadLibrary("HelloCPP");
    } 
}

HelloCPP.cpp

#include <jni.h>
#include<iostream>
#include "HelloCPP.h" 
using namespace std;

extern "C" 
JNIEXPORT void JNICALL Java_HelloCPP_print(JNIEnv *env, jobject obj){
    cout << "Hello World from C++!" << endl;
    return; 
}

В командной строке я запускаю следующее:

  • javac HelloCPP.java
  • javah -jni HelloCPP
  • 86_64-w64-mingw32-g ++ -c -I "C: \ Java \ jdk1.8.0_171 \ include" -I "C: \ Java \ jdk1.8.0_171 \ include \ win32" HelloCPP.cpp
  • x86_64-w64-mingw32-g ++ -shared -o HelloCPP.dll HelloCPP.o
  • java -Djava.library.path =.HelloCPP

Тогда печально известная ошибка связывания / загрузки DLL

Исключение в потоке "main" java.lang.UnsatisfiedLinkError: <"MyProjectDirectory">\ HelloCPP.dll: не удается найти зависимые библиотеки в java.lang.ClassLoader $ NativeLibrary.load (собственный метод) в java.lang.ClassLoader.loadLibrary0 (ClassLoader.java:1941) в java.lang.ClassLoader.loadLibrary (ClassLoader.java: 1857) в java.lang.Runtime.loadLibrary0 (Runtime.java:870) в java.lang.System.loadLibrary (System.java:1122) в HelloCPP. (HelloCPP.java:8)

Попытки решения

  • java -Djava.library.path =.Предполагается, что HelloCPP проверяет каталог текущего проекта, в котором собрана dll, и должен нормально связываться
  • Пробовал копировать dll в другую папку и добавлять этот каталог в системную переменную окружения path
  • Использовал Dependency Walker и заметил, что HelloCPP.dll ищет libstdc ++ - 6.dll и другие dll
  • Пробовал копировать эти драйверы в тот же каталог, а затем вызывает цепную реакцию, ища дополнительные dll
  • Попытка добавления команд, таких как -static-libstdc ++

Дополнительные примечания

  • Я могу запустить эту точную программу с нативным методом в C и использоватьx86_64-w64-mingw32-gcc, библиотека DLL найдена, подключена, загружена и программа работает нормально
  • x86_64-w64-mingw32-g ++ была загружена через Cygwin
  • Переключена на x86_64-w64-mingw32-g ++, потому что у меня возникла та же проблема, что и Ошибка компиляции Cygwin Проблемный кадр: # C [cygwin1.dll + 0xd6d47] с использованием JNI , когда мыing g ++
  • В настоящее время использую текстовый редактор Sublime для написания моих файлов Java и C ++, а затем компилирую через командную строку
  • Если кто-то может порекомендовать мне хорошую IDE для использования с dev с JNI, это было бы здорово
  • Первый раз, надеюсь, не пропустил ничего важного, потратил много времени на ответы на уже заданные вопросы

1 Ответ

0 голосов
/ 29 июля 2019

Java-код : helloworld.java

class helloworld{
    public native void hello();

    static {
            System.loadLibrary("hello");
    }
    public static void main(String args[]){
            new Helloworld().hello();
    }
}

код cpp : hello.c

#include<iostream>
#include "helloworld.h"
using namespace std;
JNIEXPORT void JNICALL Java_helloworld_hello(JNIEnv *env, jobject obj)
{
    cout<<"Hello World";

    return;
}

Команды

javac -h . helloworld.java
g++ -I /usr/lib/jvm/java-8-oracle/include/ -I /usr/lib/jvm/java-8-oracle/include/linux/ hello.cpp -shared -o libhello.so -fPIC
java -Djava.library.path=. helloworld
...