Я нашел хорошую реализацию JNI: https://sites.google.com/site/aminer68/jni-wrapper-for-delphi-and-freepascalИспользование JNI в FPC/Lazarus на Linux
имеет версию 2.85, и в соответствии текст был написан в марте 2016 года, но она написана для Windows.
Но у меня никаких проблем не пропуская/удаление всех связанных с Windows, материал (что Лазарь не удалить), но моя работа все еще не
Я сделал это так:
procedure TJavaRuntime.Initialize;
begin
if libHandle <> 0 then
exit; // already initialized.
FRuntimeLib := '/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so';
libHandle := LoadLibrary(PChar(FRuntimeLib));
if libHandle = 0 then
raise EJavaRuntimeCreation.Create('Could not load library ' + FRuntimeLib);
@CreateVM := getProcAddress(libHandle, 'JNI_CreateJavaVM');
@GetDefaultArgs := getProcAddress(libHandle, 'JNI_GetDefaultJavaVMInitArgs');
@GetCreatedVMs := getProcAddress(libHandle, 'JNI_GetCreatedJavaVMs');
if (@CreateVM = Nil) or (@GetDefaultArgs = Nil) or (@GetCreatedVMs = Nil) then
raise EJavaRuntimeCreation.Create('Library ' + FRuntimeLib + ' is not valid.');
vmargs2.version := $00010008;
GetDefaultArgs(@vmargs2);
end;
Вы видите, Я загружаю jvm-библиотеку по мере необходимости в Linux. libHandle становится ненулевым, поэтому я думаю, что он загружает его хорошо (если я создаю орфографическую ошибку в имени библиотеки, libHandle остается равным нулю.)
Обнаружение procadresses кажется неудачным. @CreateVM:>
Некоторые фон на CreateVM:
CreateVM : TCreateVM;
TCreateVM = function (vm : PPJavaVM ; penv : PPJNIEnv ; p : Pointer) : jint; {$IFDEF WIN32} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF}
(кстати, Cdecl активен, STDCALL неактивна в редакторе Lazarus)
Я пытаюсь вызвать один, как это функция TJavaRuntime.GetVM
Как здесь
if CreateVM(@pvm, @penv, args) <>0 then
raise EJavaRuntimeCreation.Create('Could not create JVM');
Он не переходит к исключению, но вызывает другое исключение: Проект jtest1 повышен класс исключений «Внешний: SIGSEGV». По адресу 7FFFE62582B4
Я где-то читал, что SIGSEGV входит в ячейку памяти, которая является причиной незаконного доступа к памяти. Это возвращает меня к коду, где адрес CreateVM извлекается таким образом:
@CreateVM := getProcAddress(DLLHandle, 'JNI_CreateJavaVM');
я уверен, что функция с таким именем существует в этой библиотеке:
~ > nm -D /usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so
---fragment
000000000070e0f0 T jio_snprintf
000000000070de80 T jio_vfprintf
000000000070e0d0 T jio_vsnprintf
00000000006d0880 T JNI_CreateJavaVM
00000000006cd1d0 T JNI_GetCreatedJavaVMs
00000000006cd210 T JNI_GetDefaultJavaVMInitArgs
000000000070ee00 T JVM_Accept
0000000000713990 T JVM_ActiveProcessorCount
0000000000715a20 T JVM_AllocateNewArray
0000000000727340 T JVM_AllocateNewObj
Поэтому вызов с getProcAddress (.....) не приводит к действительному адресу. Может быть, что функция LoadLibrary (PChar (FRuntimeLib)) не загружает библиотеку хорошо, хотя у нее есть действительный дескриптор. (я также попытался SafeLoadLibrary (FRuntimeLib). Или GetProcAddress (.....) есть некоторые проблемы (Кстати, я также попытался GetProcedureAddress)
Я также пробовал другие Jvm-библиотеку, так что. .? не может быть проблема
Кто знает, что происходит здесь не так
заранее спасибо
Спасибо, Марко, я нашел информацию о cmem: http://wiki.lazarus.freepascal.org/CMem Сейчас первый в моей LPR-файл. Не решает проблему. Действительно, многие stdcall's. Теперь {$ IFDEF WIN32} stdcall; {$ ENDIF} {$ IFDEF LINUX} cdecl; {$ ENDIF}, а cdecl - активны. Функции, которые я вызываю с помощью @, например CreateVM, необходимы для инициализации. Без них ничего не работает (как я хорошо понимаю). Я не знаю, правильно ли я их использую, я использую их в исходном коде. Я не понимаю ваше последнее замечание, для информации, моего кода и библиотеки находятся на одном компьютере. –
Если исходный код заголовка и код, который вы используете для вызова заголовка, относятся не к одному и тому же источнику (но для другого заголовка или заголовка), то вы рискуете, что один транслятор заголовка перевел указательный параметр с помощью VAR, а другой перевел его как pascal указатель. –
Привет, Марко, нет заголовков, используемых в Pascal loadLibrary и getProcAddress, все, что мы делаем, - это имена, которые публикуются библиотекой. Сама библиотека должна быть загружена, ручка стала ненулевой. Я проверил его, преднамеренно искажая путь, затем ручка становится нулевой. Итак, когда библиотека загружена хорошо, что я думаю, тогда проблема должна быть в вызове getProcAddress. Я также попытался загрузить другой libjvm.so, который имел тот же результат. Я думаю, что это проблема FPC/Lazarus, но я не уверен в этом. Я также разместил их в своих списках рассылки. –