UnsatisfiedLinkError: указанная процедура не найдена

Я пишу код JNI на С++ для вызова из апплета в Windows XP. Мне удалось успешно запустить апплет и загрузить библиотеку JNI и вызвать ее, даже если у нее есть функции вызова в других DLL. Я получил эту работу, установив переменную системной среды PATH, чтобы включить каталог, в котором находятся все мои DLL.

Итак, проблема заключается в том, что я добавляю другой вызов, который использует новую внешнюю DLL, и вдруг при загрузке библиотеки вызывается UnsatisfiedLinkError. Сообщение: "Указанная процедура не найдена". Это, похоже, не проблема с отсутствующей зависимой DLL, потому что я могу удалить зависимую DLL и получить другое сообщение об зависимой DLL. Из того, что мне удалось найти в Интернете, похоже, что это сообщение означает, что в DLL отсутствует встроенная реализация Java-функции, но странно, что он отлично работает без этого дополнительного бита кода.

Кто-нибудь знает, что может быть причиной этого? Какие вещи могут дать сообщение "Указанная процедура не удалось найти" для UnsatisifedLinkError?

Ответ 1

Я понял проблему. Это было скучно. Сообщение "Указанная процедура не может быть найдена" для UnsatisfiedLinkError указывает, что функция в корневой dll или в зависимой dll не найдена. Наиболее вероятной причиной этого в ситуации JNI является то, что собственная функция JNI не экспортируется правильно. Но это может произойти, если загружена зависимая DLL и что в DLL отсутствует функция, требуемая ее родителем.

В качестве примера у нас есть библиотека с именем input.dll. Порядок поиска DLL должен всегда искать в каталоге приложения сначала, а каталоги PATH - последним. Раньше мы всегда запускали исполняемые файлы из того же каталога, что и input.dll. Однако есть еще один файл input.dll в системном каталоге Windows (который находится в середине порядка поиска DLL). Поэтому, когда вы запускаете это из java-апплета, если я включаю код, описанный выше в апплете, который вызывает загрузку input.dll, он загружает файл input.dll из системного каталога. Поскольку наш код ожидает определенных функций в input.dll, которых нет (потому что это другая DLL), сбой загрузки происходит с сообщением об ошибке о пропущенных процедурах. Не потому, что функции JNI экспортируются неправильно, а потому, что была загружена неправильная зависимая DLL, и в ней не было ожидаемых функций.

Ответ 2

Существует вероятность того, что DLL была построена с использованием С++ (в отличие от C). если вы не позаботились о том, чтобы выполнить процедуру, это одна из возможных причин.

Попробуйте экспортировать все функции из библиотеки DLL. Если список включает вашу функцию, тогда вы хорошо.

Ответ 3

Обычно, когда вы связываетесь с другими библиотеками, вам нужно установить ссылку на соответствующий .lib файл. Похоже, вы не ссылаетесь на все файлы lib, которые вам нужны. Проверьте, что не связывает, и убедитесь, что вы добавили его в список для компоновщика.

Ответ 4

Вы создали новую внешнюю DLL, используя стандартную процедуру JNI? Я., используя джаву и т.д.? Если это так, то я не уверен, что не так.

Если нет, то процедура, которую вы пытаетесь вызвать, не была экспортирована (как упоминалось в anjanb). Я знаю два способа экспорта функций: отдельный список экспорта и маркировку определенных функций с помощью __declspec (dllexport).

Невозможно получить доступ к переменной в С++ DLL из приложения C, имеет немного больше информации о теме DLL.

Ответ 5

Скомпилируйте свой код С++ в режиме отладки. Затем вставьте DebugBreak(); где вы хотите начать отладку. Запустите Java-код. Когда встречается инструкция DebugBreak(), вы получите всплывающее окно с кнопкой Debug на нем. Нажмите здесь. Dev Studio откроется с вашей программой в машинный код. Перейдите к отладчику дважды, и вы сможете перешагнуть через свой исходный код.

Ответ 6

Если вы сделали все проблемы с программированием в руководствах и примерах JNI, но вы все равно получаете ту же ошибку, что и проблема, возможно, проблема может быть у вашей переменной пути. Сделайте шаги ниже и снова запустите:

  • Не забудьте установить переменную JAVA_HOME в папку JDK (не JRE, потому что JRE не содержит jni-заголовок) Пример: На панели параметров переменных среды определите var: JAVA_HOME val: C:\Program Files\Java\jdk1.7.0_11
  • добавить % JAVA_HOME%\bin к переменной пути

После выполнения этих действий ваше приложение может найти имя jni-процедуры и ссылки на JNI.dll правильно. Итак, я надеюсь, что вы не получите эту пропущенную ошибку процедуры снова.