Я создал модуль C++ для встраивания в файл общей библиотеки, а затем вызываю его из Java с помощью JNI.
У меня есть 2 среды, Windows и Unix, и у меня есть исполняемая программа на C++ и программа на Java, которые я просто перекомпилирую для каждой среды.
Когда я компилирую свою программу tester.exe в Windows и запускаю ее с помощью методов из моей библиотеки (.dll) работает нормально. Как и юникс версия.
Когда я компилирую свою Java-программу в Windows и загружаю свою библиотеку (.dll) с помощью Java loadLibrary, происходит сбой. Пишет Попытка доступа недействительный адрес.
Я не могу понять, почему он не будет работать с Java loadLibrary при работе в Windows, но он работает везде, используя тот же код. Если я откладываю загрузку зависимой DLL, которую использует моя библиотека, моя библиотека загружается на Java, но не работает. Я знаю, что есть определенный код, который вызывает проблему с загрузкой моей библиотеки Java, но я не могу понять, почему мой C++ exe не имеет проблем с теми же методами и библиотеками.
Моя dll имеет 1 открытый метод, который вызывает 4 метода из некоторых существующих библиотек.Если я прокомментирую эти 4 метода, моя dll нормально загрузится в Java. Я знаю, что это как-то связано с этими методами из библиотеки, на которую ссылается моя dll. Есть ли что-то другое в том, как Java видит зависимые библиотеки? Я попытался сначала загрузить зависимые библиотеки, но один из загружаемых файлов dll вызывает ошибку рекурсии, и стек переполняется.
Кто-нибудь знает, как обойти DLL, вызывающую переполнение стека из-за ошибки рекурсии? Мне нужны методы в нем, но я не могу загрузить его с помощью java loadLibrary.
Вот более подробная информация о задействованных файлах и фактических сообщениях об ошибках. Я добавил DllMain в свой исходный файл dll, чтобы посмотреть, что и когда загружается. Если ту же программу (my_plain_dll_to_call_JNI_DLL) скомпилировать как exe-файл, то все работает нормально. Если я скомпилирую его и загружу из своей Java-программы, это произойдет.
Я написал имя файла, отображающее текст слева от каждой строки, чтобы показать, на каком уровне выполняется выполнение.
c:\java myJavaProgram
myJavaProgram: Java Static Method Entry.
myJavaProgram: Java Calling System.loadLibrary(my_plain_dll_to_call_JNI_DLL)
my_JNI_DLL.dll: Entering DllMain
my_JNI_DLL.dll: DLL_PROCESS_ATTACH
my_plain_dll_to_call_JNI_DLL: DLL_PROCESS_ATTACH
my_plain_dll_to_call_JNI_DLL: DLL_THREAD_ATTACH
my_plain_dll_to_call_JNI_DLL: DLL_THREAD_DETACH
my_plain_dll_to_call_JNI_DLL: DLL_PROCESS_DETACH
myJavaProgram: my_plain_dll_to_call_JNI_DLL Loaded!
myJavaProgram: Java Static Method Exit.
myJavaProgram: Entering Main().
my_plain_dll_to_call_JNI_DLL: In call_my_JNI_DLL_method
my_JNI_DLL.dll: In my_JNI_DLL_method
my_JNI_DLL.dll: Entering my_JNI_DLL_CheckEnvironmentVariables()
my_JNI_DLL.dll: Exiting my_JNI_DLL_CheckEnvironmentVariables
my_JNI_DLL.dll: Calling StartExistingNativeCode.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (0xc0fb007e), pid=7500, tid=7552
#
# JRE version: 6.0_21-b06
# Java VM: Java HotSpot(TM) Client VM (17.0-b16 mixed mode, sharing windows-x86 )
# Problematic frame:
# C [KERNELBASE.dll+0x9673]
#
# An error report file with more information is saved as:
# C:\hs_err_pid7500.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
my_plain_dll_to_call_JNI_DLL: DLL_PROCESS_DETACH
my_JNI_DLL.dll: Entering DllMain
my_JNI_DLL.dll DLL_PROCESS_DETACH
Обновление Я сузил проблему до библиотеки управления памятью, которая связана с другой dll, которую использует моя программа.Используемая dll — это sh33w32.dll, она называется SmartHeap и, по-моему, принадлежит компании Microquil. У меня версия 3.3, и когда Java LoadLibrary пытается загрузить эту dll, происходит сбой. Я не уверен, что я мог бы сделать, чтобы java-дескриптор загружал эту библиотеку. Это должно иметь какое-то отношение к области памяти, к которой может получить доступ Java, а не к тому, к чему Windows разрешает доступ exe. У exe нет проблем с библиотекой SmartHeap, но Java не позволит мне ее использовать. Любые идеи или опыт борьбы с этим? Я попытался удалить связанную библиотеку, перекомпилировав другие библиотеки, но тогда обычные вызовы в коде перестали работать.
Найдена дополнительная информация Функция в dll, которая не загружается в java, называется MemRegisterTask. Это продукт под названием SmartHeap от Microquill. Вот документация, которую я нашел об этой функции. Я думаю, что это распределение памяти является причиной того, что java не может ее загрузить.
MemRegisterTask инициализирует библиотеку SmartHeap. На большинстве платформ вам не нужно вызывать MemRegisterTask, потому что SmartHeap инициализируется при первом вызове.
SmartHeap поддерживает счетчик регистрационных ссылок для каждой задачи или процесса. Каждый раз, когда вы вызываете MemRegisterTask, этот счетчик ссылок увеличивается. Если ваш последний вызов SmartHeap происходит до того, как ваше приложение будет готово к завершению, вы можете вызвать MemUnregisterTask для завершения работы SmartHeap.MemUnregisterTask уменьшает счетчик регистрационных ссылок на единицу — когда счетчик равен нулю, SmartHeap освобождает всю память, выделенную SmartHeap, и состояние отладки, связанное с текущей задачей или процессом.