Исключение в потоке "main" java.lang.UnsatisfiedLinkError: com.printer.PrinterWinAPI.GetStatus (Ljava / lang / String;) J - PullRequest
0 голосов
/ 13 ноября 2018

Вот моя проблема: я пытаюсь использовать JNI в своем проекте Java как способ общения с Win32 API. Я получаю эту ошибку во время выполнения в затмении:

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.printer.PrinterWinAPI.GetStatus(Ljava/lang/String;)J
at com.printer.PrinterWinAPI.GetStatus(Native Method)
at com.printer.PrinterWinAPI.<init>(PrinterWinAPI.java:14)
at com.printer.PrinterWinAPI.main(PrinterWinAPI.java:25)

Но что действительно странно в моей проблеме, так это то, что я могу успешно скомпилировать свой проект, используя cmd:

javac PrinterWinAPI.java

Затем программа работает нормально, запустив:

java PrinterWinAPI

Насколько я понимаю, eclipse успешно находит мой файл .dll, но не может найти функцию GetStatus () внутри файла. Я попытался скомпилировать его, используя Visual Studio как в x86 и x86_64, так и в mingw gcc в x86 и x86_64. Вот мои файлы:

Java-файл, который реализует интерфейс JNI: PrinterWinAPI.java

package com.printer;

public class PrinterWinAPI {
    static {
        System.load("C:\\GetPrinterStatus.dll");
    }

    public Long         status;
    public String       name;

    public PrinterWinAPI(String printerName) {
        this.name = printerName;
        this.status = this.GetStatus(this.name);
    }

    private native long GetStatus(String str);

    public static void main(String[] args) {
        PrinterWinAPI printer = new PrinterWinAPI("PRINTER NAME EXAMPLE");
        System.out.println(printer.status);
    }
}

PrinterWinAPI.h, созданный с использованием javah PrinterWinAPI:

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

#ifndef _Included_PrinterWinAPI
#define _Included_PrinterWinAPI
#ifdef __cplusplus extern "C" {
#endif /*  * Class:     PrinterWinAPI  * Method:    
GetStatus  * Signature: (Ljava/lang/String;)J  */ 
JNIEXPORT jlong JNICALL Java_PrinterWinAPI_GetStatus   (JNIEnv *, jobject, jstring);

#ifdef __cplusplus }
#endif
#endif

и вот сам файл PrinterWinAPI.c:

#include "PrinterWinAPI.h"   // Generated
#include <windows.h>
#include <wincon.h>
#include <winspool.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <io.h> 

// Implementation of the native method
JNIEXPORT jlong JNICALL Java_PrinterWinAPI_GetStatus(JNIEnv *env, 
jobject thisObj, jstring str) {
        //some stuff...
    return (int64_t)dwStatus;
 }

Еще раз, программа компилируется и работает нормально, используя javac, javah и java из командной строки, я на 99% уверен, что проблема в затмении, но я действительно не знаю, с чего начать. Я потратил несколько часов на поиск решения в Интернете, но ничего не смог найти. Почему я не могу затмить мой проект, а бинарные файлы java, запускаемые вручную, могут?

Мой jre / jdk - это сборка 1.8.0_101-b13 64-бит

Затмение: выпуск кислорода 3.а (4.7.3а)

ОС: Windows 7, 64-битная

1 Ответ

0 голосов
/ 14 ноября 2018

@ user2543253 Спасибо, это сработало!Он был правильно скомпилирован, потому что мой java-файл не был в пакете, поэтому заголовок был правильным, но поскольку java-файл был вложен в пакет в моем проекте, правильный заголовок был Java_com_printer_PrinterWinAPI_GetStatus вместо Java_PrinterWinAPI_GetStatus.

...