Android Studio下JNI调用与编译so包

本文介绍了如何在Android中利用JNI和NDK实现C语言功能并编译为so库,包括创建native方法、生成C头文件、配置NDK路径及编译so库等步骤。
  2个月前做一款IM软件的时候,手机录音的声音比较小,所以就找了一些声音的增益库,在网上找了一遍最后选择了webrtc的声音增益模块。webrtc源码是c,所以如果要在android中使用的话,就必须将该模块打包成so库文件然后用java调用这个库。
  这里就不得不说一下JNI是什么了。

  JNI是什么?

  JNI(Java Native Interface)意为JAVA本地调用,它允许Java代码和其他语言写的代码进行交互,简单的说,一种在Java虚拟机控制下执行代码的标准机制。

  NDK是什么?

  Android NDK(Native Development Kit )是一套工具集合,允许你用像C/C++语言那样实现应用程序的一部分。

  为什么要用NDK?

  1、安全性,java是半解释型语言,很容易被反汇编后拿到源代码文件,我们可以在重要的交互功能使用C语言代替。
  2、效率,C语言比起java来说效率要高出很多(该不该使用jni这个需要结合项目环境需求,并不一定使用jni效率就比java高)。

  JNI和NDK的区别?

  从工具上说,NDK其实多了一个把.so和.apk打包的工具,而JNI开发并没有打包,只是把.so文件放到文件系统的特定位置。从编译库说NDK开发C/C++只能能使用NDK自带的有限的头文件,而使用JNI则可以使用文件系统中带的头文件。从编写方式说,它们一样。

  JNI具体的介绍就不多说了,网上很多的,这里主要讲一下编译so库和调用。之前是在eclipse里边编译的so库,相对来说比较起android studio麻烦一些,因为编译过程中又使用到了cygwin。

  下面说说在android studio中编译so库,首先新建一个工程

新建一个类,并写一个native方法,用来调用so库中的方法

下一步就是清空工程,然后再编译工程

直到build目录下出现classes目录

接着使用命令生成c的头文件

使用命令进入到项目build目录下的debug目录


然后再使用javah -jni 类的包名加类名


如果java环境没错的话就会在debug目录下生产一个头文件


生产了头文件然后在src/main目录下新建一个jni的目录用来存放c的代码文件


将刚刚生成的c的头文件拷贝到jni目录下,文件的名字可以改


之后新建一个.c的文件,这个文件用来实现头文件中的方法,首先来看看生成的头文件的内容

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_caidongdong_contentprovider_util_JniUtil */

#ifndef _Included_com_caidongdong_contentprovider_util_JniUtil
#define _Included_com_caidongdong_contentprovider_util_JniUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_caidongdong_contentprovider_util_JniUtil
 * Method:    getStringFromC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_caidongdong_contentprovider_util_JniUtil_getStringFromC
  (JNIEnv * env, jobject obj);

#ifdef __cplusplus
}
#endif
#endif
这个头文件是不用改的,下面贴上.c文件的内容

#include "mystring.h"
#include <string.h>
JNIEXPORT jstring JNICALL Java_com_caidongdong_contentprovider_util_JniUtil_getStringFromC
        (JNIEnv * env, jobject obj){
    return (*env)->NewStringUTF(env,"Hello from JNI !");
}
这个c文件的内容需要自己写的,首先引入头文件,使用#include 引入需要的头文件,这个跟java的import类似,但是有区别。拷贝生成的头文件中的方法到c文件中,注意要把行参补全


然后写上该方法的实现,当然这里只是简单的返回一个字符串,多说一句c和c++的方法有些是有区别的,所以写的时候注意选择。

c文件写好之后就可以配置编译环境,编译需要ndk我这里使用的ndk的版本是android-ndk-r11,下载好解压后在Android studio中配置ndk路径



选择ndk的路径


下一步,启用ndk编译,需要在gradle.properties中配置

android.useDeprecatedNdk=true




下一步,需要在app的build.gradle中的defaultConfig配置ndk生成的so库名称依据生成多个平台的包


下一步,在含有native方法的类中加载so库

public class JniUtil {
    static {
        System.loadLibrary("my_lib");
    }
    public  native String getStringFromC();
}

然后在activity中使用该类并调用其中的方法

        JniUtil jniUtil = new JniUtil();
        content.setText(jniUtil.getStringFromC());

最后的运行效果图


在工程目录下的lib并没有生成so库,因为gradle已经自动的帮我们生成好了,工程目录下就有,如果反编译apk的话,就会发现so库是存在于lib中的。




内容概要:本文以DVWA漏洞靶场中的命令注入漏洞为切入点,结合通信行业5G网管系统的实际应用场景,深入剖析了命令注入的攻击原理防御机制。通过对比低级别(Low)存在漏洞的代码高级别(Impossible)安全加固后的代码,详细展示了攻击者如何利用未过滤的用户输入执行恶意系统命令,并进一步提出白名单验证、输入拆分重组、输出编码等关键技术手段实现有效防护。文章强调在通信行业高度依赖自动化运维的背景下,此类漏洞可能导致核心网元被渗透、配置被篡改,因此必须采取代码层系统层相结合的纵深防御策略。此外,文中还展望了未来在5G MEC、SDN等新技术环境下,零信任架构AI驱动的安全审计将成为重要发展方向。; 适合人群:具备一定网络安全基础知识,从事通信行业网络运维、安全开发或系统架构工作的技术人员,以及关注Web安全工业级代码防护的研发人员。; 使用场景及目标:①理解命令注入漏洞在通信网管系统中的真实危害攻击路径;②掌握工业级安全编码实践,提升对输入验证、输出编码、权限控制等核心安全机制的应用能力;③为5G网络管理系统安全加固提供可落地的技术参考; 阅读建议:学习时应结合DVWA靶场动手复现文中案例,重点分析漏洞形成条件防御代码的设计逻辑,并延伸思考如何将“最小权限原则”和“参数化执行”应用于自身业务系统中,强化安全开发意识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值