Как вызвать внешнюю функцию DLL из кода Java

Мне нужно вызвать функцию внешней библиотеки DLL из кода Java. Я использую Netbeans 7.2. Функции моей DLL:

Boolean  isValid(string  word)
List<String> getWords(String  word)

Я следую этому примеру. Но я не знаю, как объявить мои функции DLL. И я нашел другую ссылку. Но это не работает для меня.

4 ответа

Я наткнулся на ту же проблему "вызова DLL из Java" и сначала был разочарован сложностью. Тем не менее, есть элегантное решение (может быть также интересным для людей, живущих там в месте обитания processing.org.) Учитывая довольно "общую" форму вопроса (возможно, понижение рейтинга не оправдано для этого), я полагаю, было бы указано довольно легкое решение. Другими словами, решение, позволяющее избежать путаницы с заголовочными файлами, дополнительными преобразованиями и т. Д., Так же как и исходный код, не обязательно доступно.

Моя рекомендация для этого была бы JNA ( https://github.com/twall/jna), которая в основном является упрощающей оболочкой для JNI. Это прекрасно работает, отображение типов является простым (например, pchar = lpcstr buffer -> string), хотя я использую его только для библиотек Windows и моих собственных библиотек C-стиля, созданных с использованием Delphi-Pascal. Единственное, что нужно учитывать, - это то, что возвращаемые значения должны экспортироваться через функции, а не "помеченные" ссылочные переменные. Вопрос уже указывает на связанный источник, который обеспечивает пример для этого (таким образом, ответы вокруг JNI могут быть здесь неуместны). Обратите внимание, что ссылка, которую я предоставил, также содержит примеры для переноса массивов и указателей.

Вам нужно будет использовать собственный интерфейс Java (JNI), который представляет собой набор функций C/C++, которые позволяют нативному коду взаимодействовать с кодом Java (т. Е. Получать параметры из вызовов функций Java, возвращать результаты и т. Д.). Напишите библиотеку C-оболочки, которая принимает вызовы JNI, а затем вызывает вашу внешнюю библиотеку.

Например, следующая функция вызывает метод updateHandlers на нативный объект (который хранится так же долго на стороне Java).

class MyImpl {
  void updateHandlers(JNIEnv *env) {
    this->contentHandler = ....;
  }
}

JNIEXPORT void JNICALL Java_package_Classname_updateHandlers0
  (JNIEnv *env, jobject obj, jlong ptr) 
{
  ((MyImpl*)ptr)->updateHandlers(env);
}

Соответствующие объявления в package.ClassName:

private long ptr; //assigned from JNI
public void updateHandlers() {
   if (ptr==0) throw new NullPointerException(); 
   updateHandlers0(ptr);
}
private native void updateHandlers0(long ptr);

static {
    try {
          /*try preloading the library external.dll*/
      System.loadLibrary("external");
    } catch (UnsatisfiedLinkError e) {
      /*library will be resolved when loading myjni*/
    }
    System.loadLibrary("myjni"); //load myjni.dll
}

Некоторое время назад я написал пример учебного пособия, возможно, это поможет.

http://wendro.blogspot.com/2010/03/jni-example-eclipse-dev-cpp.html

Вы объявляете свои нативные функции в Java (native private ...) с подписью, которая вам нужна; затем беги javah (инструмент, который поставляется с JDK) для генерации собственных заголовков. List<String> (на самом деле Listиз-за типа стирания) является jobject в нативном коде.

Соответствующий метод C будет:

JNIEXPORT jobject JNICALL package_Classname_getWords(JNIEnv *env, jobject jobj, jstring word)

Я думаю, что было бы проще вернуть массив строк jobjectArrayи создать экземпляр списка в Java из возвращенных значений. Смотрите этот пример.

Другие вопросы по тегам