首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从德尔菲调用JNI_OnLoad

从德尔菲调用JNI_OnLoad
EN

Stack Overflow用户
提问于 2018-02-07 18:07:27
回答 1查看 372关注 0票数 1

我有一个本机c++库,我想在我的delphi项目中使用它;下面是我想从Delphi代码部分调用它的重要部分:

代码语言:javascript
复制
#include <jni.h>
#include <android/log.h>

#define  LOG_TAG    "EmbJniTest"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)


JavaVM* gJavaVM = NULL;
//------------------------------------------------------------------------
jint JNI_OnLoad(JavaVM* aVm, void* aReserved)
{
 // cache java VM
 gJavaVM = aVm;
 JNIEnv* env;// latter on it'll be used as global var
 LOGI("JVM INIT");
 if (aVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
 {
  LOGI("Failed to get the environment");
  return -1;
 }
 return JNI_VERSION_1_6;
}

下面是我的delphi代码部分来加载我的库:

代码语言:javascript
复制
LIBNAME = 'libtest.so';


function try_load_dll:integer;
var libPath:system.string;
begin
  _status:= 0 ;
  libPath:=TPath.Combine(tpath.GetLibraryPath,libname);
  _status := LoadLibrary(PChar(libPath));
  result:=_Status;
  if( _status= 0 )then exit;
end;

问题是

代码语言:javascript
复制
JNI_OnLoad

从未被调用;我在logcat中看不到任何关于它的日志。

我读过JNI_OnLoad的调用是由System.loadLibrary()完成的。如果您不使用它来加载库,JNI_OnLoad就不会发生。

不管怎么说,我可以从我的这里代码中调用它。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-07 23:11:08

只是想知道为什么没有调用JNI_OnLoad

如果JNI_OnLoad()是加载您的本机库(即当Java代码调用System.loadLibrary()时),则Java通常会调用它。

因为在您的示例中不是这样的,这就是为什么您的JNI_OnLoad()没有被调用。您自己直接加载库,因此您必须自己调用JNI_OnLoad()

Embarcadero在TJNI_OnLoad单元中声明一个Embarcadero.Jni函数指针类型。使用GetProcAddress()获取指向库导出的JNI_OnLoad()函数的指针,并将该指针分配给TJNI_OnLoad变量。然后,您可以像调用任何其他函数一样调用JNI_OnLoad()

稍后,我将将JNIEnv* env保存为全局变量,以便在本机库中的某些过程和函数中使用它。

JNI_OnLoad()以一个JavaVM*指针作为输入。调用JNI_OnLoad()的人必须传入指向有效JavaVM对象的指针。

Java通常会为您处理这个问题。但是,由于您是自己加载库,因此必须自己调用JNI_OnLoad(),所以您必须从Delphi代码中提供一个JavaVM对象。与其自己调用JNI_CreateJavaVM(),不如使用Delphi的RTL内部使用的相同的JavaVM对象--RTL的System单元中的JavaMachine指针(只需将其键入到PJavaVM,这也是在Embarcadero.Jni单元中声明的)。

试试这个:

代码语言:javascript
复制
uses
   ..., Embarcadero.Jni

const
  LIBNAME = 'libtest.so';

function try_load_dll: THandle;
var
  libPath: string;
  OnLoadFunc: TJNI_OnLoad;
  hlib: THandle;
begin
  Result := 0;
  libPath := TPath.Combine(TPath.GetLibraryPath, libname);
  hlib := LoadLibrary(PChar(libPath));
  if hlib = 0 then Exit;
  @OnLoadFunc := GetProcAddress(hlib, 'JNI_OnLoad');
  if not Assigned(OnLoadFunc) then
  begin
    FreeLibrary(hlib);
    Exit;
  end;
  OnLoadFunc(PJavaVM(System.JavaMachine), nil);
  Result := hlib;
end;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48670592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档