Member 12373848 Ответов: 1

Проблема при вызове метода DLL из приложения javafx


Я разрабатываю приложение JavaFX и библиотеку dll C++, метод которой я хочу вызвать из JavaFX (java-код). Итак, я поместил dll в каталог проекта , получив рабочий каталог во время выполнения , следовательно, создав путь к dll, установив то же значение пути в "java.library.path" и затем загрузив dll в статический блок. После загрузки, когда я пытаюсь получить доступ к методу dll, каждый раз я получаю "неудовлетворенный LinkError".

Пожалуйста, направьте меня с этим вопросом. Работает ли приложение JavaFX JNI??

Ниже приведен код :
один файл находится в пакете jni, а другой-в пакете xyz.
package jni;

public class Test{

    static {
        try {
            System.out.println("Current Directory :" + System.getProperty("user.dir"));
            String path = System.getProperty("user.dir") + "\\dll";
            System.setProperty("java.library.path", path);
            System.loadLibrary("Test");
            System.out.println("Loaded DLL");
            System.out.println("java.library.path : " + System.getProperty("java.library.path"));
        } catch (UnsatisfiedLinkError ex) {
            System.out.println("\n Link Issue :" + ex.getStackTrace());
        } finally {

        }

    }

    public static native void nativeTest();

    public static void NativeTestJni() {
        try {
            System.out.println("\n Called Frm MEthod");
            nativeTest();
        } catch (UnsatisfiedLinkError ex) {
            System.out.println("\n Erase Called from Method");
        } finally {

        }

    }

}


вызов вышеуказанного метода из Main.java
package xyz;

import jni.Test
import javafx.scene.image.Image;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

public class TestJNI extends Application {

 
    @Override
    public void start(Stage stage) throws Exception {
        
        primaryStage.setTitle("My First JavaFX App");

        primaryStage.show();

        Test.NativeTestJni();
        System.out.println("\n called ended frm obj");
    }

    public static void main(String[] args) {
        launch(args);       
    }

 }


Я получаю правильное значение для пути библиотеки, которую я печатаю. BT, когда я пытаюсь вызвать метод из DLL, он говорит
java.lang.reflect.InvocationTargetExceptio Caused by: java.lang.UnsatisfiedLinkError: jni.Test.nativeTest()V


Пожалуйста, помогите мне с вышеуказанной проблемой , в dll я печатаю только "Привет". Его nt comimg up.

Обновление кода C++: сгенерированный заголовочный файл с использованием javah на тестовом классе и, следовательно, написанный cpp-код соответственно.

Header File : jni_Test.h


/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jni_Test */

#ifndef _Included_jni_Test
#define _Included_jni_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jni_Test
 * Method:    nativeTest
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jni_Test_nativeTest
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif


C++ File : jni_Test.cpp


#include "stdafx.h"
#include <jni.h>
#include <iostream>
#include <stdio.h>
#include "jni_Test.h"
using namespace std;

JNIEXPORT void JNICALL Java_jni_Test_nativeTest
(JNIEnv *, jclass){
    std::cout << "Hello JNI !!";
    printf("Hello JNI Print !!!!!");
    return;
}


Что я уже пробовал:

Пробовал много способов, но всегда получал "UnsatisfiedLinkError".

Richard MacCutchan

Где находится код для библиотеки DLL?

Member 12373848

Я обновил Dll (код C++) выше, пожалуйста, просмотрите то же самое и дайте мне знать, если я что-то пропустил.

Richard MacCutchan

Я не вижу ничего плохого в вашем коде и сравнил его со своим старым проектом, но все выглядит правильно. Единственная разница заключается в том, что вы объявили собственный метод статическим, а моя версия-нет. К сожалению, я не могу проверить это, так как моя версия Java 64-битная, а VS-32-битная.

Richard MacCutchan

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

public native void nativeTest(); // remove static keyword

public static void NativeTestJni() {
try {
System.out.println("\n Called Frm MEthod");
new Test().nativeTest(); // call native function on an object

Не забудьте перезапустить javah, а затем перестроить библиотеку DLL.

Member 12373848

большое вам спасибо за вашу помощь , я уже работаю над этим. Сообщу вам об этом с обновлениями

1 Ответов

Рейтинг:
1

KarstenK

Вызываемая функция неправильно экспортируется с помощью JNI из вашей библиотеки dll C, возможно, это просто неправильный тип данных в качестве параметров. Первый-это ВСЕГДА указатель JNI.

Вот такой прекрасный вид руководство где все объяснено.

JNI работает таким образом, поэтому позаботьтесь о том, чтобы реализовать c-dll таким образом.


Member 12373848

Спасибо за ваше руководство. Я сгенерировал заголовочный файл с помощью Javah и, соответственно, написал код на C++. Я обновил часть кода dll (C++) в приведенном выше разделе. Пожалуйста, просмотрите то же самое и дайте мне знать, если я что-то пропустил

KarstenK

Поскольку эти вызовы "дороги", ваш тестовый объект должен быть членом класса и создать несколько шагов раньше. JNI имеет ленивое время выполнения!!!

Richard MacCutchan

Нет, проблема в том, что был объявлен собственный метод static, так что не будет никаких this ключевое слово.