热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JNI打包综合论述(Linuxso,Androidso,windll)

前言    在实际开发中不同语言不同平台使用的加载使用的JNI包是不同的,在android平台中生成的多渠道*.so包并不能在直接Linux平台上使用。并且在windows上需要使

前言

       在实际开发中不同语言不同平台使用的加载使用的JNI包是不同的,在android平台中生成的多渠道*.so包并不能在直接Linux平台上使用。并且在windows上需要使用dll。现在就有这样一个场景,一个算法so包需要在Android端使用,也需要在后端使用,后端服务器不定,可能是Linux也可能是winServer。

目录

前言

Android-so

Linux-so (可复用时,不可复用时 JDK准备,GCC/G++)

1、可复用环境时

2、不可复用时

Windows-dll

Android-so

有很多博客关于android-so如何进行打包,早期的jni方式原文链接,还有就是在建立Android项目时默认支持C++,项目创建后目录会自动生成cpp文件夹,这种方式默认使用Cmake,可以很好地进行混合编译其他so包。

关于android studio3.3升级后没有include c++ support,在创建项目时,select a Project Template滑到最后就可以找到Native C++,这正是我们需要创建的项目。

《JNI打包综合论述(Linux-so,Android-so,win-dll)》

创建流程完毕后,我们将在项目中看cpp文件以及已经生成好的模板代码。

《JNI打包综合论述(Linux-so,Android-so,win-dll)》

可以自行对模板代码进行编辑,然后执行gradle中的 externalNativeBuildRelease 命令

《JNI打包综合论述(Linux-so,Android-so,win-dll)》

生成的so包将在app下图所示的目录中找到

《JNI打包综合论述(Linux-so,Android-so,win-dll)》

这样的方法比较方便与快捷。

 

Linux-so (可复用时,不可复用时 JDK准备,GCC/G++)

1、可复用环境时

在linux环境下打包主要依赖当前环境下的JDK环境,gcc、g++,如果可以复用java类JNI头文件,则只需要加入jni_md.h、jni.h这两个头文件即可

如下环境:CentOS7.4 /AMD64

jni.h所在目录:usr/java/${your_jdk_version_folder}/include/jni.h

《JNI打包综合论述(Linux-so,Android-so,win-dll)》

jni_md.h所在目录:usr/java/${your_jdk_version_folder}/include/linux/jni_md.h

 

《JNI打包综合论述(Linux-so,Android-so,win-dll)》

 此时,新建一个目录中,包含

  • ${java类头文件}.h
  • jni.h
  • jni_md.h
  • ${c源码文件}.c/${c++源码文件}.cpp

此时在此目录打开终端,执行

    c语言:gcc  *.c  -fPIC -shared -o libname.so

    c++语言:g++ *.cpp -fPIC -shared -o libname.so

2、不可复用时

2.1检查JDK是否安装,终端输入java -version

2.2gcc/g++,注意检查版本号,源代码使用C语言对应使用gcc,源代码使用C++语言对应使用g++;

[juan@juan~]$ gcc --version
gcc (GCC) 4.6 . 3 20120306 (Red Hat 4.6 . 3 - 2 )
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[qiaoning@qiaoning ~]$ g++ --version
bash: g++: command not found...
[qiaoning@qiaoning ~]$ gcc --version
gcc (GCC) 4.6 . 3 20120306 (Red Hat 4.6 . 3 - 2 )
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

2.3关于头文件及源码的处理

建议使用android文件中生成的头文件与源码 ,若只需要在linux环境下进行打包操作,则可以进行下面的操作:

 

2.3.1建立Java类:

public class JNITest{
static {
try {
System.loadLibrary("JNITest" );
} catch (UnsatisfiedLinkError e) {
e.printStackTrace();
}
}
public native int add(int value1, int value2);
}

 

在终端输入 javac JNITest.java 后生成JNITest.class 文件

然后:javah Hello 生成 Hello.h文件

 2.3.1 在相同的目录下建立JNITest.cpp:

#include "JNITest.h"
#include
// 与 Hello.h 中函数声明相同
JNIEXPORT void JNICALL Java_Hello_SayHello (JNIEnv * env, jobject arg, jint value1,jint value2)
{
return value1+value2;
}

此时进入 1可复用环境步骤,在上面。

2.4 最后是java测试代码:

public class ADDTest
{
public static void main(String argv[])
{
JNITest test = new JNITest();
int result = test.add(90,90);
System.out.print("JNITest result:" + result);
}
}

测试成功会打印:“JNITest result:180”

2.5 注意事项:

1 . 如果可以通过 TCP/IP 实现 Java 代码与本地 C/C++ 代码的交互工作,那么最好不使用以上提到的 JNI 的方式,因为一次 JNI 调用非常耗时,大概要花 0.5 ~ 1 个毫秒。

2 . 在一个 Applet 应用中,不要使用 JNI。因为在 applet 中可能引发安全异常。

3 . 将所有本地方法都封装在单个类中,这个类调用单个 DLL。对于每种目标操作系统,都可以用特定于适当平台的版本替换这个 DLL。这样就可以将本地代码的影响减至最小,并有助于将以后所需的移植问题包含在内。

4 . 本地方法要简单。尽量将生成的 DLL 对任何第三方运行时 DLL 的依赖减到最小。使本地方法尽量独立,以将加载 DLL 和应用程序所需的开销减到最小。如果必须要运行时 DLL,则应随应用程序一起提供它们。

5 . 本地代码运行时,没有有效地防数组越界错误、错误指针引用带来的间接错误等。所以必须保证保证本地代码的稳定性,因为,丝毫的错误都可能导致 Java 虚拟机崩溃。

 

Windows-dll

在window环境需要使用到jni需要将源码打包成dll是形式,其工具可以参考GCC打包dll文件-MinGW-w64 C/C++编译器,其步骤与Linux是一致的。

 

 


推荐阅读
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了关系型数据库和NoSQL数据库的概念和特点,列举了主流的关系型数据库和NoSQL数据库,同时描述了它们在新闻、电商抢购信息和微博热点信息等场景中的应用。此外,还提供了MySQL配置文件的相关内容。 ... [详细]
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
  • Mono为何能跨平台
    概念JIT编译(JITcompilation),运行时需要代码时,将Microsoft中间语言(MSIL)转换为机器码的编译。CLR(CommonLa ... [详细]
  • Question该提问来源于开源项目:react-native-device-info/react-native-device-info ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 负载均衡_Nginx反向代理动静分离负载均衡及rewrite隐藏路径详解(Nginx Apache MySQL Redis)–第二部分
    nginx反向代理、动静分离、负载均衡及rewrite隐藏路径详解 ... [详细]
  • 第四讲ApacheLAMP服务器基本配置Apache的编译安装从Apache的官方网站下载源码包:http:httpd.apache.orgdownload.cgi今 ... [详细]
author-avatar
台艾辉_435
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有