Исключение в потоке main java.lang.UnsatisfiedLinkError: RunnerClass.parsecmdline(ILjava/lang/String;)V

У меня есть тестовый пример, когда я пытаюсь получить доступ к коду C из моей программы Java с помощью JNI. Необходимые шаги следующие:

<сильный>1. Программа Java, вызывающая собственные методы:

public class RunnerClass{
    public native void win32_svc_install();
    static{
        System.loadLibrary("testDll");
                System.out.println("library loaded successfully");   
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new RunnerClass().win32_svc_install();
    }

}

<сильный>2. Теперь, после создания файла .class и создания соответствующего файла .h, я поместил реализацию собственного метода в файл .c.

    /* DO NOT EDIT THIS FILE - it is machine generated */
//RunnerClass.h

#include <jni.h>
/* Header for class RunnerClass */

#ifndef _Included_RunnerClass
#define _Included_RunnerClass
#ifdef __cplusplus
extern "C" {
#endif/*
 * Class:     RunnerClass
 * Method:    nx_win32_svc_install
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_RunnerClass_win32_1svc_1install
  (JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif

Файл RunnerClass.c содержит реализацию собственного метода внутри него. Что именно будет делать этот метод, так это вызывать ServiceManager окон, чтобы использовать его. Моя программа Java должна выполнять эти действия.

Теперь проблема возникает после создания testDll.dll. Перед интерпретацией кода Java я установил путь к требуемой библиотеке (testDll) в файле java.library.path.

Теперь, когда я запускаю свою программу, моя библиотека загружается, но выдает UnsatisfiedLinkError собственному методу. Точная ошибка выглядит следующим образом:

Exception in thread "main" hello ,java.lang.UnsatisfiedLinkError: RunnerClass.win32_svc_install(ILjava/lang/String;)V
    at RunnerClass.win32_svc_install(Native Method)
    at RunnerClass.main(MainWs.java:58)

Я провел много исследований и до сих пор понял, что исключение выдается из-за того, что программа не может найти реализацию нативного метода в загружаемой библиотеке.


person Abhishek    schedule 16.03.2013    source источник
comment
Что за функция parsecmdline()?   -  person millimoose    schedule 16.03.2013
comment
Похоже, что собственный метод пытается вызвать метод Java, а метод Java не может быть найден. У вас есть исходный код нативного метода?   -  person Joni    schedule 16.03.2013
comment
@millimose: это была ошибка. Это было отредактировано сейчас.   -  person Abhishek    schedule 16.03.2013
comment
@Joni: я не получаю твой комментарий? Моя программа JAVA имеет собственное объявление метода, определение которого находится внутри файла [.c], который после сборки создает файл [.dll]. Ни один собственный метод не вызывает метод java.   -  person Abhishek    schedule 16.03.2013
comment
Как вы запускаете свое приложение, через командную строку или IDE? Как именно вы устанавливаете свойство java.library.path?   -  person Byron    schedule 16.03.2013
comment
Кроме того: если все, что вам нужно, это запустить вашу Java-программу как службу, используйте эту: оболочку. tanukisoftware.com/doc/english/index.html   -  person millimoose    schedule 16.03.2013
comment
JNA также должен быть менее ужасным вариантом для большинства случаев, когда вы будете использовать JNI. Он должен поставляться с полной привязкой Win32.   -  person millimoose    schedule 16.03.2013


Ответы (1)


Исключение как-то не соответствует вашему коду. В Java вы объявляете функцию как

public native void win32_svc_install();

В С++ вы объявляете функцию как

JNIEXPORT void JNICALL Java_RunnerClass_win32_1svc_1install (JNIEnv *, jobject);

Я думаю, что это должно быть объявлено как

JNIEXPORT void JNICALL Java_RunnerClass_win32_svc_install (JNIEnv *, jobject);

Но помимо странной "1" в объявлении c++, кажется, есть еще одна проблема. Обе функции объявлены правильно как функция void с нулевыми аргументами.

Но в вашем исключении указано, что оно ищет функцию void с тем же именем, но с целым числом и строковым аргументом:

RunnerClass.win32_svc_install(ILjava/lang/String;)V

Глядя на ваш код, я не могу понять, почему. Я попытался воспроизвести это, переименовав одну из моих функций C++; следующее исключение неудовлетворенной ссылки правильно указало определенные параметры.

person user2328447    schedule 26.05.2013