为了账号安全,请及时绑定邮箱和手机立即绑定

请问在Android里很多java 文件调用native函数?

/ 猿问

请问在Android里很多java 文件调用native函数?

犯罪嫌疑人X 2019-08-06 09:04:33

Android很多java 文件调用native函数为何没有System.loadLibrary或System.load


查看完整描述

5 回答

?
qq_ACE_34

请问一下     5月份 你的myelipse      你的代码报错 但是文件不报错 是如何解决的。  能简单描述一下吗


查看完整回答
反对 回复 2019-08-23
?
慕哥6287543

AVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。

JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。

简单介绍及应用如下:

一、JAVA中所需要做的工作

在JAVA程序中,首先需要在类中声明所调用的库名称,如下:

static {

System.loadLibrary(“goodluck”);

}

在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。

还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需要具体实现。如下:

public native static void set(int i);

public native static int get();

然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。

例如程序testdll.java,内容为:

public class testdll

{

static

{

System.loadLibrary("goodluck");

}

public native static int get();

public native static void set(int i);

public static void main(String[] args)

{

testdll test = new testdll();

test.set(10);

System.out.println(test.get());

}

}

用javac testdll.java编译它,会生成testdll.class。

再用javah testdll,则会在当前目录下生成testdll.h文件,这个文件需要被C/C++程序调用来生成所需的库文件。

二、C/C++中所需要做的工作

对于已生成的.h头文件,C/C++所需要做的,就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面,就可以用JAVA调用C/C++所实现的功能了。

接上例子。我们先看一下testdll.h文件的内容:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class testdll */

#ifndef _Included_testdll

#define _Included_testdll

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: testdll

* Method: get

* Signature: ()I

*/

JNIEXPORT jint JNICALL Java_testdll_get

(JNIEnv *, jclass);

/*

* Class: testdll

* Method: set

* Signature: (I)V

*/

JNIEXPORT void JNICALL Java_testdll_set

(JNIEnv *, jclass, jint);

#ifdef __cplusplus

}

#endif

#endif

在具体实现的时候,我们只关心两个函数原型

JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);



JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);

这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而jint是以JNI为中介使JAVA的int类型与本地的int沟通的一种类型,我们可以视而不见,就当做int使用。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。参数中,我们也只需要关心在JAVA程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。

好,下面我们用testdll.cpp文件具体实现这两个函数:

#include "testdll.h"

int i = 0;

JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)

{

return i;

}

JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)

{

i = j;

}
编译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件。并且名称要与JAVA中需要调用的一致,这里就是goodluck.dll

把goodluck.dll拷贝到testdll.class的目录下,java testdll运行它,就可以观察到结果了。



查看完整回答
反对 回复 2019-08-23
?
饮歌长啸

android不是标准的jvm,只是使用了java的语法,其他基本都是自己发明的
连字节码格式都不一样

另外,你去看标准javase里面也有很多本地方法没有用那些加载
因为那些本地方法是jvm实现的,不是用第三方动态库实现的

比如 Math.sin 方法,都是jvm自己的


查看完整回答
反对 回复 2019-08-23
?
UYOU

解决java调dll报Unable to load library的错误可以尝试以下方法:
  载入库文件有两个函数,System.load 和 System.loadLibrary。
  当使用System.load时,需要输入文件的全路径,例如:System.load(“/tmp/test.so”);
  当使用System.loadlibrary时是在系统的library 的目录中需找复合条件的库文件,可以使用-Djava.library.path=[path]参数,来指定Java程序加载库文件的路径,或者将库文件(*.so,*.dll)复制到include的默认路径,Linux一般是/usr/lib目录下,当然你可以编辑/etc/ld.so.conf.d/下的文件,设定自己的库查找路径ldconfig -v|grep xxx看看有没有你的动态库。
  Linux还要注意,使用System.loadLibrary(name)方法其中参数内容与Windows有区别,Linux中的的库文件名为libname.so,Windows为name.dll。
  在Windows中尽量使用Windows的C/C++编译器生成dll文件,否则会出现问题。
  不过具体问题还要具体对待!


查看完整回答
反对 回复 2019-08-23
?
皈依舞

1、必须确保设定的路径下有需要加载的dll文件
2、jar是64位,则dll文件必须也是64位,如果jar是32位,则dll文件必须也是32位;
3、PlayCtrl INSTANCE = (PlayCtrl) Native.loadLibrary("soft\\hikvision\\PlayCtrl", PlayCtrl.class);
其中"soft\\hikvision\\PlayCtrl"可以是绝对路径,也可以是相对路径,但是,路径分隔符必须是\,不能是/,(这里使用\\是因为第一个\是转义字符)(别问我为什么,我也不知道,我就是这样改了之后就可以了)
4、在Tomcat中调用时,可将dll文件放在src目录下,编译后会自动存放到WebRoot\WEB-INF\classes\路径下,在调用时可使用如下方法:
String path = HCNetSDK.class.getResource("/").getPath()+"HCNetSDK.dll";
// 如何tomcat路径中有空格,加上这句path=path.replaceAll("%20", " ");
// 上述方法获取的path最前边第一个字符是/,如【/d:/RTSMS_x64/Servent/HCNetSDKCom/HCNetSDK.dll】
所以我用了以下方法
String path = (HCNetSDK.class.getResource("/").getPath()+"HCNetSDK.dll").replaceAll("%20", " ").substring(1).replace("/", "\\");
HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary(path,HCNetSDK.class);




查看完整回答
反对 回复 2019-08-23

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信