「java加载.so」java加载jar包

博主:adminadmin 2022-11-22 16:25:09 61

今天给各位分享java加载.so的知识,其中也会对java加载jar包进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

java 调用so文件

用JNI实现

实例:

创建HelloWorld.java

class HelloWorld

{

private native void print();

public staticvoid main(String[] args)

{

new HelloWorld().print();

}

static

{

System.loadLibrary("HelloWorld");

}

}

注意print方法的声明,关键字native表明该方法是一个原生代码实现的。另外注意static代码段的System.loadLibrary调用,这段代码表示在程序加载的时候,自动加载libHelloWorld.so库。

编译HelloWorld.java

在命令行中运行如下命令:

javac HelloWorld.java

在当前文件夹编译生成HelloWorld.class。

生成HelloWorld.h

在命令行中运行如下命令:

javah -jni HelloWorld

在当前文件夹中会生成HelloWorld.h。打开HelloWorld.h将会发现如下代码:

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

#include jni.h

/* Header for class HelloWorld */

#ifndef _Included_HelloWorld

#define _Included_HelloWorld

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: HelloWorld

* Method: print

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_HelloWorld_print

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

该文件中包含了一个函数Java_HelloWorld_print的声明。这里面包含两个参数,非常重要,后面讲实现的时候会讲到。

实现HelloWorld.c

创建HelloWorld.c文件输入如下的代码:

#include jni.h

#include stdio.h

#include "HelloWorld.h"

JNIEXPORT void JNICALL

Java_HelloWorld_print(JNIEnv *env, jobject obj)

{

printf("Hello World!\n");

}

注意必须要包含jni.h头文件,该文件中定义了JNI用到的各种类型,宏定义等。

另外需要注意Java_HelloWorld_print的两个参数,本例比较简单,不需要用到这两个参数。但是这两个参数在JNI中非常重要。

env代表java虚拟机环境,Java传过来的参数和c有很大的不同,需要调用JVM提供的接口来转换成C类型的,就是通过调用env方法来完成转换的。

obj代表调用的对象,相当于c++的this。当c函数需要改变调用对象成员变量时,可以通过操作这个对象来完成。

编译生成libHelloWorld.so

在Linux下执行如下命令来完成编译工作:

cc -I/usr/lib/jvm/java-6-sun/include/linux/

-I/usr/lib/jvm/java-6-sun/include/

-fPIC -shared -o libHelloWorld.so HelloWorld.c

在当前目录生成libHelloWorld.so。注意一定需要包含Java的include目录(请根据自己系统环境设定),因为Helloworld.c中包含了jni.h。

另外一个值得注意的是在HelloWorld.java中我们LoadLibrary方法加载的是

“HelloWorld”,可我们生成的Library却是libHelloWorld。这是Linux的链接规定的,一个库的必须要是:lib+库

名+.so。链接的时候只需要提供库名就可以了。

运行Java程序HelloWorld

大功告成最后一步,验证前面的成果的时刻到了:

java HelloWorld

如果你这步发生问题,如果这步你收到java.lang.UnsatisfiedLinkError异常,可以通过如下方式指明共享库的路径:

java -Djava.library.path='.' HelloWorld

当然还有其他的方式可以指明路径请参考《在Linux平台下使用JNI》。

我们可以看到久违的“Hello world!”输出了。

关于Android开发中Java对于.so库的调用

厂家并没有欺骗你或者是含糊你的意思,确实是只提供给你jar包以及 so 库就可以了,做法是这样子的:

1.比如我现在在用net.sqlcipher.database 这个加密库(网上能搜得到的,用于数据库加密)。 那么我现在就在项目用加载这个jar包(在你的项目单击右键-》属性-》Java Build Path-》Libraries-》Add Jars,选择提供给你的jar包,我这里是 sqlcipher.jar,然后在Order and Export勾选你刚刚加载的 jar包。)

2.打开你的workspace目录,在你的项目目录下创建一个文件夹libs(如果文件夹不存在的话),然后将提供给你的so库放入该目录,基本架构就算是搭建好了。

3.进行开发,这里你需要问一下提供给你jar包的厂家,基本的用法,否则的话是无法进行开发的,因为你都不知道怎么去用。 sqlcipher的基本用法是:

SQLiteDatabase.loadLibs(this); //加载 so库文件,你的厂家的方法应该也是类似。

File databaseFile = getDatabasePath(SQLite_toll.DATABASE_NAME);

databaseFile.mkdirs();

databaseFile.delete();

SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databaseFile, helper_SharedPreferences.get_str_sp("database_cipher",this), null);

SQLite_toll initToll = new SQLite_toll(this, avaSys);

initToll.onCreate(database);

database.close();

//因为我sqlcipher是用于数据库加密的,所以你所看到的都是数据库的一些方法,你厂家提供给你的jar包的用法,你是要去问他们的,或者他们的是否有开源代码,又或者是网上也有很多人使用,那么能搜到相关资料。

根据你补充的提问,那么就是System.loadLibrary(this); ,就可以调用了

ndk java加载2个so

这里不能够发链接,建议直接在百度上搜:“android ndk 动态库_百度经验”,头版头条就是我发的,一共有四种方法,希望对你有用,我是ndk吧吧主,有问题可以到ndk吧给我留言,谢谢!

安卓JVM加载so库流程

好久没有写点东西发了,工作中的事情有点杂,也找不到整块东西可以写的。

最近调查了一个问题,稍微追了一下流程,这里记录一下。

由于我们支持的设备相对比竞品,zygote进程多占用了好几倍的内存空间。通过dump meminfo后发现,我们的设备在so库,ttf,和unkonwn mmap的内存空间相比竞品一共大了20多M,其中so库多了15M左右。

通过查看zygote进程的smaps,确定了占用空间最大的几个so库确实是我们自己的。虽然确定了内存占用大的原因,还是得把这些so库是加载在zygote进程中的时机确定了才行。

我的第一反应就是在zygote启动时,加载sharedLibrary()时,把这些库加载了,于是去看了这部分源码,并没有。

通过反复调试以及追踪源码,最后发现是在JVM启动的过程中加载了这些so库,这些so库的配置在“system/etc/public.libraries.txt”下。

这个文件里配置的都是public的so库,能够被普通app访问的。类似的配置文件还有“vendor/etc/”下面的,还有一些其他的配置地方,我没有深入去看,想要看的盆友可以自己去看源码或者注释。

下面我就带大家一起看看虚拟机加载这些so库的流程。

调用栈:

frameworks/base/cmds/app_process/app_main.cpp

----runtime.start("com.android.internal.os.ZygoteInit", args, zygote);

frameworks/base/core/jni/AndroidRuntime.cpp

----AndroidRuntime::startVm

---JNI_CreateJavaVM(pJavaVM, pEnv, initArgs)

art/runtime/jni/java_vm_ext.cc

---android::InitializeNativeLoader();

system/core/libnativeloader/native_loader.cpp

----Initialize()

----ReadConfig(public_native_libraries_system_config, sonames, always_true, error_msg)

其中,public_native_libraries_system_config 为 system/etc/public.libraries.txt

这部分流程是在安卓设备开机过程中的,在执行ZygoteInit.main()之前会先启动java虚拟机的,这样fork其他java进程的时候,java环境就已经有了,不用再创建虚拟机了。

最后贴一下Initialize()函数:

Java 在eclipse中,web项目如何加载.so文件的详细步骤

引入jna.jar包。 然后写一个接口类继承Library来和.so(linux平台)或.dll(windows平台)文件交互。接口中对应的方法为so中的方法,大小写都需要完全一致,同时参数类型也需要注意,jna和so中的参数类型的对应转换。

以下是代码是大概例子,你可以看一下,是有参数的对应格式的。其中,Native.loadLibrary为加载链接库文件。

public interface LibVlc extends Library {

    Info INFO = Info.getInstance();

    LibVlc INSTANCE = (LibVlc)Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);

    LibVlc SYNC_INSTANCE = (LibVlc)Native.synchronizedLibrary(INSTANCE);

    String libvlc_errmsg();

    void libvlc_clearerr();

  

    libvlc_instance_t libvlc_new(int argc, String[] argv);

}

linux上使用java加载so动态库报错

1、编写 java 类,先上代码

[html] view plain copy

package com.hongquan.jni;

public class HelloJNI {

// 声明 so 库中的方法

public native static String sayHi(String name);

// 载入 so 动态链接库

static {

System.load("/home/hongquan/main.so");

}

// java 类入口函数

java加载.so的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java加载jar包、java加载.so的信息别忘了在本站进行查找喔。

The End

发布于:2022-11-22,除非注明,否则均为首码项目网原创文章,转载请注明出处。