пытаюсь создать dll «Hello Word» в Visual Studio, которую примет Java Native Access
-
19-09-2019 - |
Вопрос
Я успешно скомпилировал свою библиотеку на Linux и Mac и использовал ее с Java Native Access.К сожалению, ничего из того, что я делаю, похоже, не работает с компилятором Visual Studio и Java Native Access.
Я возвращаюсь к основам и пытаюсь создать очень простую dll в Visual Studio, с которой будет работать Java Native Access, буду признателен за любую помощь.
Вот GimmeFiveDll.c:
__declspec(dllexport) int gimmeFive()
{
return 5;
}
Вот SystemLibrary.java:
import com.sun.jna.Native;
public class SystemLibrary {
public static final SystemLibrary instance = new SystemLibrary();
static {
Native.register("GimmeFiveDll");
}
public native int gimmeFive();
}
Я уже пробовал переключить интерфейс вызова на stdcall в Visual Studio.Я не вносил никаких других изменений в пустую консольную библиотеку dll проекта мастера нового проекта по умолчанию.В приведенном выше примере полученная dll даже не экспортирует функцию правильно в соответствии с dumpbin.exe /exports
.Мой реальный проект экспортирует их правильно, но в любом случае я всегда получаю одно и то же исключение JNA:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'GimmeFiveDll': The specified module could not be found.
(Да, я поместил GimmeFiveDll.dll в System32.Да, я могу использовать JNA для доступа к другим библиотекам DLL в System32, поставляемым с Windows).
Кто-нибудь готов помочь мне завершить этот минималистичный пример библиотеки dll, созданной Visual Studio, которая нравится JNA?
Большое большое спасибо.
Решение
После двух дней биения головой о стену я понял это.Проблема заключалась в том, что C:\Windows\System32 НЕ является каталогом, из которого System.loadLibrary() (который использует Native.register()) может загружать dll на 64-битной машине!Поэтому вместо этого JNA, очевидно, пыталась скопировать библиотеку во временное место и загрузить ее, но это не удалось.Сообщение «указанный модуль не найден» не очень помогло и навело меня на неверный путь :-\
В любом случае, чтобы ответить на мой собственный вопрос, вот пример dll, который можно построить с помощью MSVC, который может использовать Java (и JNA) (просто поместите его в правильный каталог для вашей системы!):
GimmeFiveDll.c:
#ifdef __cplusplus
#error no C++, to keep this example simple
#endif
__declspec(dllexport) int gimmeFive()
{
return 5;
}
DllTest.java:
import com.sun.jna.Native;
public class DllTest {
static {
Native.register("GimmeFiveDll");
}
public static native int gimmeFive();
public static void main(String[] args) {
System.out.println("I got: " + DllTest.gimmeFive());
}
}
Если все пойдет хорошо, Java напечатает «Я получил:5".
Обратите внимание, что я не счел необходимым менять настройки компилятора для использования stdcall или объявлять __stdcall в сигнатуре функции.Фактически, никаких изменений в компиляторе обычного пустого проекта dll, создаваемого мастером, не потребовалось.