UnsatisfiedLinkError с использованием JNI

В настоящее время я пытаюсь использовать JNI, чтобы использовать собственный код для получения ширины и высоты консоли, но я продолжаю получать эту ошибку:

Exception in thread "main" java.lang.UnsatisfiedLinkError: project.console.NativeConsole.getConsoleWidth()I
at project.console.NativeConsole.getConsoleWidth(Native Method)
at project.Core.main(Core.java:14)

Я искал в Интернете, что это за исключение и как его исправить, но безуспешно

это мой текущий код:

Main.java

package project;

import project.console.NativeConsole;

public class Core {

    public static void main(String[] args) {
        NativeConsole console = new NativeConsole();
        console.getConsoleWidth();
    }

}

NativeConsole.java

package project.console;

public class NativeConsole {

    static {
        System.loadLibrary("NativeConsole");
    }

    public native int getConsoleWidth();
    public native int getConsoleHeight();
    public native void clearConsole();

}

dll написана на C++ и представляет собой файлы .cpp и .h, скомпилированные в файл .dll.

cpp файл:

#include <jni.h>
#include <stdio.h>
#include <windows.h>
#include "project_console_NativeConsole.h"

/*
 * Class:     project_console_NativeConsole
 * Method:    getConsoleWidth
 * Signature: ()I
 */
JNIEXPORT jint JNICALL     Java_project_console_NativeConsole_getConsoleWidth(JNIEnv *env, jobject obj) {
    CONSOLE_SCREEN_BUFFER_INFO inf;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &inf);
    return (jint) inf.dwSize.X;
}

/*
 * Class:     project_console_NativeConsole
 * Method:    getConsoleHeight
 * Signature: ()I
 */
JNIEXPORT jint JNICALL     Java_project_console_NativeConsole_getConsoleHeight(JNIEnv *env, jobject obj) {
    CONSOLE_SCREEN_BUFFER_INFO inf;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &inf);
    return (jint) inf.srWindow.Bottom - inf.srWindow.Top;
}

/*
 * Class:     project_console_NativeConsole
 * Method:    clearConsole
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_project_console_NativeConsole_clearConsole(JNIEnv *env, jobject obj) {
    system("cls");
    return;
}

Я не знаю, могу ли я сейчас включить дополнительную информацию, но мой текущий вопрос: почему я получаю это исключение? потому что я думаю, что это немного расплывчато.

Похоже, он не может найти DLL.

Tripp Kinetics 06.04.2018 20:07

нет, это вызов метода, который создает ошибку, если бы он не смог найти библиотеку, он бы выдал эту ошибку pastebin.com/ratDBWA9

Human 06.04.2018 20:09

В дополнение к комментарию Триппа, возможно, у вас нет нужных прав доступа к вашему файлу dll.

Richard Tran 06.04.2018 20:13

Я тестирую ваш код, и он работает. Какую команду вы используете для компиляции?

Jorn Vernee 06.04.2018 20:42

я использую g++ -shared -o NativeConsole.dll -I"C:\Program Files (x86)\Java\jdk1.8.0_161\include" -I"C:\Program Files (x86)\Java\jdk1.8.0_161\include\win32" .\project_console_NativeConsole.cpp .\project_console_NativeConsole.h для компиляции файлов

Human 06.04.2018 20:47

@Human хм у меня тоже отлично работает ... А вы вообще не трогали заголовочный файл?

Jorn Vernee 06.04.2018 20:53

нет, у меня нет, если размещение его в другом каталоге не означает, что он сломает его, но я так не думаю

Human 06.04.2018 20:55

@Human Вы можете проверить, действительно ли созданная DLL экспортирует три собственных метода и действительно ли это 32-битная dll.

Robert 06.04.2018 20:57

как я могу это точно проверить?

Human 06.04.2018 21:09

Вы можете проверить это с помощью инструмента Microsoft depends (с новой, легко доступной версией по адресу dependencywalker.com). Выберите нужную 32-битную или 64-битную сборку. Попробуйте также функцию профиля с помощью команды java.exe.

Tom Blodget 08.04.2018 22:43

Это 64-битный Cygwin? Кажется, я помню другие вопросы, когда JNI с 64-битным Cygwin не работал.

user2543253 09.04.2018 12:22

нет, я использую mingw64, i686-7.3.0-posix-dwarf-rt_v5-rev0

Human 10.04.2018 13:13

То же самое и с mingw64. Я нашел несколько сообщений, в которых рекомендуется использовать опцию компоновщика --kill-at. Может ты мог бы попробовать это.

user2543253 10.04.2018 13:58
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
13
58
0

Другие вопросы по теме