2008-10-01 3 views
10

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

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

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

ответ

14

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

+0

У меня была эта проблема. libA вытащил libBv2 и libC. Оба libBv2 и libC были найдены. Проблема заключалась в том, что libC зависел от другой версии libBv1. libBv1 и libBv2 не работали вместе. зависимый ходок показывал библиотеки, но я не расширил зависимости libC. Я использовал procmon (http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx), чтобы увидеть загружаемые библиотеки, и именно тогда я заметил, что загружается вторая версия libB. – codeDr 2014-01-28 23:11:38

0

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

2

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

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

+0

Я открыл DLL в PE-проводнике и дважды проверил, что функции JNI экспортируются с использованием C-ссылки. Я также дважды проверял, и сигнатуры функций JNI выглядят одинаково в случае, когда DLL загружается без ошибок и в случае, если она терпит неудачу. – matt 2008-10-07 13:13:31

0

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

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

Can't access variable in C++ DLL from a C app содержит дополнительную информацию по теме DLL.

+0

Я использую стандартную процедуру JNI. Как я уже сказал, в некоторых случаях я работаю. Но когда я добавляю этот дополнительный код, он внезапно перестает работать с данной ошибкой. Как было указано, ошибка указывает, что функция не экспортируется, но я уверен, что функции экспортированы. – matt 2008-10-07 14:47:42

0

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

0

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

  1. Будьте уверены вы установите переменную JAVA_HOME в папку JDK (не JRE, поскольку JRE оленья кожа содержит JNI заголовок) Пример: На переменной окружения панели настройки определяют вар: JAVA_HOME Вэл: C: \ Program Files \ Java \ jdk1.7.0_11
  2. добавить % JAVA_HOME% \ Bin в путь переменной

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