UnsatisfiedLinkError: указанная процедура не найдена - PullRequest
11 голосов
/ 02 октября 2008

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

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

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

Ответы [ 6 ]

16 голосов
/ 08 октября 2008

Я разобрался в проблеме. Это было глупо. Сообщение «Указанная процедура не может быть найдена» для 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 голосов
/ 02 октября 2008

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

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

0 голосов
/ 15 января 2015

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

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

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

0 голосов
/ 20 октября 2009

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

0 голосов
/ 03 октября 2008

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

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

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

0 голосов
/ 02 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...