如何将c语言封装JNI接口供java程序调用

百度内推,可文末扫码加微信

一、jni是什么?为什么会有jni的存在?

JNI是Java Native Interface的缩写,中文可译为Java本地调用,它允许Java代码和其他语言写的代码进行交互,而我们在使用JNI的时候是让其与C语言通信,我们知道C语言是偏底层的语言,可以直接操作硬件,执行效率较高,这个时候JNI就派上了用场,可以通过JNI直接调用c语言的函数。JNI这个概念听着好像很神秘的感觉,其实总结下来就是俩句话“产生头文件”,“实现头文件定义的函数”。下面我们分析一下如何实现这俩句话。

二、JNI接口的实现

首先需要实现.java文件,该java文件中定义了我们C语言函数的接口,定义java文件为StarMultiClient.java,文件中内容如下:

package stl.startimes;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;

public class StarMultiClient
{    
	public static native int StarMultiClientInit(int argc,String[] argv,String certificate_path);
    public static native int StarMultiClientTerm();
    public static native int StarMultiClientPrePlayStart(String gateway_ip,String multi_ip,int multi_port);
    public static native int StarMultiClientPrePlayStop(String multi_ip,int multi_port);

	 static 
	 { 
	    try{ 
	        System.loadLibrary("StarMultiClient");
	    } catch(UnsatisfiedLinkError e) 
	    { 
	        System.err.println("Cannot load MULTI_CLIENT library:\n " + 
	        e.toString()); 
	    } 
	 }
}

如上代码中public定义的函数,即是最终我们要实现的C语言函数。StarMultiClient是最终我们提供给java程序调用的库的命名,比如libStarMultiClient.so,java程序在运行的时候会去调用System.loadLibrary来加载这个库,加载之后就可以调用我们封装的接口了。

写好java文件后生成我们的头文件,
javac StarMultiClient.java
javah StarMultiClient
通过这俩步即可自动生成stl_startimes_StarMultiClient.h的头文件。内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class stl_startimes_StarMultiClient */
#include "stl_type.h"
#ifndef _Included_stl_startimes_StarMultiClient
#define _Included_stl_startimes_StarMultiClient
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: stl_startimes_StarMultiClient
* Method: StarMultiClientInit
* Signature: (I[Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_stl_startimes_StarMultiClient_StarMultiClientInit
(JNIEnv *, jclass, jint, jobjectArray, jstring);

/*
* Class: stl_startimes_StarMultiClient
* Method: StarMultiClientTerm
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_stl_startimes_StarMultiClient_StarMultiClientTerm
(JNIEnv *, jclass);

/*
* Class: stl_startimes_StarMultiClient
* Method: StarMultiClientPrePlayStart
* Signature: (Ljava/lang/String;Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_stl_startimes_StarMultiClient_StarMultiClientPrePlayStart
(JNIEnv *, jclass, jstring, jstring, jint);

/*
* Class: stl_startimes_StarMultiClient
* Method: StarMultiClientPrePlayStop
* Signature: (Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_stl_startimes_StarMultiClient_StarMultiClientPrePlayStop
(JNIEnv *, jclass, jstring, jint);

#ifdef __cplusplus
}
#endif
#endif

这些生成的函数就是我们需要实现的函数,可以看到这些函数只是在我们的.java文件中定义的函数基础上加了一些前缀而已,无需关心,javah过程自己干的,我们只需要去实现这些函数即可。

创建一个与第二步中同名的.c文件,这里是stl_startimes_StarMultiClient.c,然后实现第二步生成的头文件中的所有函数即可。注意实现过程是用C语言实现的,jstring,jint类型都需要转换成我们C语言的类型,以及使用完这些类型需要及时释放,类型转换与释放变量可以去百度搜索,大把大把的。
以上.C完成之后我们就可以去编译了,编译的时候需要利用NDK的环境,可自行去网上下载,ndk安装完成后我们需要写安卓的makefile用于编译我们的.c文件,这里涉及到俩个makefile,一个是Android.mk,一个是Application.mk,其中Application.mk指定了要生成的库文件是属于
什么架构的,以及使用的安卓API版本

Application.mk内容如下:
APP_PLATFORM = android-18 ## (这里使用的是android-18,只要是android-15版本以上现在的安卓设备基本都支持)
APP_ABI := armeabi armeabi-v7a ##(这里指定了编译出的库所支持的架构,这是安卓的俩个主流架构,基本可以囊括现有安卓设备)

Android.mk内容如下:
LOCAL_PATH := $(call my-dir) ##声明当前路径

include $(CLEAR_VARS) ##清理环境变量
LOCAL_MODULE := stl_client_android_v1.00.00_debug ##要连接的库
LOCAL_SRC_FILES := ( L O C A L P A T H ) / . . / l i b / (LOCAL_PATH)/../lib/ (LOCALPATH)/../lib/(TARGET_ARCH_ABI)/libstl_client_android_v1.00.00_debug.a #指定链接的库
include $(PREBUILT_STATIC_LIBRARY) ##声明编译时连接先前存在的静态库

include $(CLEAR_VARS)

LOCAL_C_INCLUDES +=
$(LOCAL_PATH)/
$(LOCAL_PATH)/…/
$(LOCAL_PATH)/…/include ##声明头文件路径

#连接的静态库
LOCAL_STATIC_LIBRARIES := stl_client_android_v1.00.00_debug

#要生成的.so库名称。java代码System.loadLibrary(“StarMultiClient”);加载的就是它
LOCAL_MODULE := StarMultiClient

#要编译的C文件
LOCAL_SRC_FILES := $(LOCAL_PATH)/…/client.c stl_startimes_StarMultiClient.c
LOCAL_LDLIBS := -lc
LOCAL_LDLIBS += -llog

##声明编译出动态库
include $(BUILD_SHARED_LIBRARY)

编译过程,首先执行export PATH=/opt/android-ndk-r10e:$PATH,指定ndk的路径,然后在.c所在文件夹下执行ndk-build,即可生成库文件libStarMultiClient.so

三、JNI的输出文件

经过编译后生成了很多文件,那么哪些是需要打包给安卓端的呢?

libStarMultiClient.so 我们的库文件,提供给安卓的接口都在这个文件实现的。

StarMultiClient.java java文件,安卓会通过这个文件中定义的类去调用我们的函数

StarMultiClient.class 字节码文件,需要给安卓虚拟机启动的时候加载使用,才可以使用我们的类

最好再输出一个接口说明文档供调用者阅读使用。详细说明jni接口的出入参数,返回值以及函数介绍。

扫一扫,可加楼主微信,一起交流C语言,嵌入式等IT技术。在这里插入图片描述
声明:本文原创,码字不易,版权必究,编辑转载请注明链接出处与原作者。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
系统根据B/S,即所谓的电脑浏览器/网络服务器方式,运用Java技术性,挑选MySQL作为后台系统。系统主要包含对客服聊天管理、字典表管理、公告信息管理、金融工具管理、金融工具收藏管理、金融工具银行卡管理、借款管理、理财产品管理、理财产品收藏管理、理财产品银行卡管理、理财银行卡信息管理、银行卡管理、存款管理、银行卡记录管理、取款管理、账管理、用户管理、员工管理等功能模块。 文中重点介绍了银行管理的专业技术发展背景和发展状况,随后遵照软件传统式研发流程,最先挑选适用思维和语言软件开发平台,依据需求分析报告模块和设计数据库结构,再根据系统功能模块的设计制作系统功能模块图、流程表和E-R图。随后设计架构以及编写代码,并实现系统能模块。最终基本完成系统检测和功能测试。结果显示,该系统能够实现所需要的作用,工作状态没有明显缺陷。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。进入银行卡列表,管理员可以进行查看列表、模糊搜索以及相关维护等操作。用户进入系统可以查看公告和模糊搜索公告信息、也可以进行公告维护操作。理财产品管理页面,管理员可以进行查看列表、模糊搜索以及相关维护等操作。产品类型管理页面,此页面提给管理员的功能有:新增产品类型,修改产品类型,删除产品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值