Вот моя проблема: я пытаюсь использовать 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-битная