NDK学习笔记-JNI开发流程
JNI(Java Native Interface)Java本地化接口,Java调用C/C++,C/C++调用Java的一套API接口
实现步骤
- 在Java源文件中编写native方法
public native static String getStringFromC();
- 到Java源代码src路径下,使用
javah
命令生成.h
头文件
注意:此处的参数为包名+类名
//生成的头文件为:com_cj5785_jni_JniTest.h
javah com.cj5785.jni.JniTest
- 复制.h头文件到CPP工程中,修改文件包含
//生成的C函数名:Java_完整类名_函数名
#include "jni.h" //将#include <jni.h>修改
复制jni.h和jni_md.h文件到CPP工程中
jni.h和jni_md.h位于Java安装目录下实现.h头文件中声明的函数
//为与头文件相匹配,此时将实现文件取名为:com_cj5785_jni_JniTest.c
#include "com_cj5785_jni_JniTest.h"
//函数实现
JNIEXPORT jstring JNICALL Java_com_cj5785_jni_JniTest_getStringFromC
(JNIEnv *env, jclass jcls)
{
//将C的字符串转换为Java的字符串
return (*env)->NewStringUTF(env, "C String");
}
生成dll文件,供Java调用
Debug -> 平台(x64) -> 确定
项目(右键) -> 属性 -> 配置属性 -> 常规 -> 生成dll动态库将生成的dll文件放在Java的src目录同级下,加载动态库
static{
System.loadLibrary("");
}
整个java项目文件源代码
package com.cj5785.jni;
public class JniTest {
static {
System.loadLibrary("JNITest");
}
public native static String getStringFromC();
public static void main(String[] args) {
String str = getStringFromC();
System.out.println(str);
}
}
运行以后在控制台输出:C String
在生成的dll过程中,会生成在相应配置的目录下
JNI说明
JNIEnv与env
JNIEnv:结构体指针
env:二级指针
JNIEnv代表Java运行环境,调用Java中的代码
在C中
JNIEnv:结构体指针别名
env:二级指针在C++中
JNIEnv:一个结构体指针的别名
env:一级指针为何需要传入JNIEnv?
C函数执行过程中需要JNIEnvC++为何没有传入?
C++中有this指针,可以拿到当前指针,对C语言而言,要修改指针的值,只能通过二级指针C++对C进行封装,给一个变量赋值为指针,这个变量就是二级指针
struct JNINativeInterface_;
struct JNIEnv_;
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv;
#endif
jclass说明
jclass代表native方法所属类的class对象,这里代表了JniTest.class
C与C++的实现
在函数实现的时候是不一样的
c实现:
#include "com_cj5785_jni_JniTest.h"
JNIEXPORT jstring JNICALL Java_com_cj5785_jni_JniTest_getStringFromC
(JNIEnv *env, jclass jcls)
{
return (*env)->NewStringUTF(env, "C String");
}
C++实现
JNIEXPORT jstring JNICALL Java_com_cj5785_jni_JniTest_getStringFromC
(JNIEnv *env, jclass jcls)
{
return env->NewStringUTF("C String");
}
JNIEnv实现模拟
//JNIEnv结构体的指针别名
typedef struct JNINativeInterface_* JNIEnv;
//结构体
struct JNINativeInterface_ {
char* (*NewStringUTF)(JNIEnv*, char*);
};
//函数实现
char* NewStringUTF(JNIEnv* env, char* str){
//在NewStringUTF执行过程,仍然需要JNIEnv
return str;
}
void main(){
//实例化结构体
struct JNINativeInterface_ struct_env;
struct_env.NewStringUTF = NewStringUTF;
//结构体指针
JNIEnv e = &struct_env;
//结构体的二级指针
JNIEnv *env = &e;
//通过二级指针调用函数
char* str = (*env)->NewStringUTF(env,"abc");
}
NDK学习笔记-JNI开发流程的更多相关文章
- NDK学习笔记-JNI多线程
前面讲到记录到ffmpeg音视频解码的时候,采用的是在主线程中进行操作,这样是不行的,在学习了POSIX多线程操作以后,就可以实现其在子线程中解码了,也可以实现音视频同步了 简单示例 在native实 ...
- NDK学习笔记-JNI的引用
JNI中的引用意在告知虚拟机何时回收一个JNI变量 JNI引用变量分为局部引用和全局引用 局部引用 局部引用,通过DeletLocalRef手动释放对象 原因 访问一个很大的Java对象,使用之后还用 ...
- NDK学习笔记-JNI的异常处理与缓存策略
在使用JNI的时候,可能会产生异常,此时就需要对异常进行处理 异常处理 JNI抛出Throwable异常,在Java层可以用Throwable捕捉 而在C只有清空异常这种处理 但如果在JNI中通过Th ...
- NDK学习笔记-JNI数据类型和属性方法的访问
JNI实现了C/C++与Java的相互访问,那么这篇文章就从C/C++访问Java开始说起 native函数说明 每个native函数,都至少有两个参数(JNIEnv *和jclass或jobject ...
- JNI开发流程-JNI/NDK【转】
本文转载自:http://wiki.jikexueyuan.com/project/jni-ndk-developer-guide/workflow.html 开发流程 JNI 全称是 Java Na ...
- JNI/NDK开发指南(一)—— JNI开发流程及HelloWorld
转载请注明出处:http://blog.csdn.net/xyang81/article/details/41777471 JNI全称是Java Native Interface(Java本地接口)单 ...
- VSTO学习笔记(三) 开发Office 2010 64位COM加载项
原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...
- Django:学习笔记(1)——开发环境配置
Django:学习笔记(1)——开发环境配置 Django的安装与配置 安装Django 首先,我们可以执行python -m django --version命令,查看是否已安装django. 如果 ...
- Android:日常学习笔记(8)———开发微信聊天界面
Android:日常学习笔记(8)———开发微信聊天界面 只做Nine-Patch图片 Nine-Patch是一种被特殊处理过的PNG图片,能够指定哪些区域可以被拉升,哪些区域不可以.
随机推荐
- 为什么说Redis是单线程的以及Redis为什么这么快!(转)
一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据”,复杂一点的会问到缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级等问题,这些看似 ...
- 题解 [CF332C] Students' Revenge
题面 解析 辣鸡题面毁我青春 因为翻译的题面中写了一句\(剩下的n−k个不会完成\). 所以就以为剩下的\(n-k\)个都会算上不满意值. (然而事实是只有\(p-k\)个...) 首先根据主席的规则 ...
- sqlserver 插入语句
//--创建事务 Create PROC [dbo].[proc_XXXXX] ) AS BEGIN BEGIN TRAN BEGIN TRY .....................插入 COMM ...
- MFC 静态文本框
窗体上操作控件内容,需要句柄,在控件处使用鼠标右键——添加变量. DoDataExchange()函数会自动生成代码,把ID与变量绑定(即DDX_Control(pDX, IDC_TEXT, objT ...
- 【Python之路】特别篇--服务商API认证、Restful、一致性哈希
API加密方式 1/ 加密方式: Md5 (随机字符串 + 时间戳) 2/ 发送方式: http://127.0.0.1:8888/index?pid= MD5加密值 | 时间戳 | 序号 服务端接收 ...
- PHP mysqli_next_result() 函数
定义和用法 mysqli_next_result() 函数为 mysqli_multi_query() 准备下一个结果集. 语法 mysqli_next_result(connection); 执 ...
- 012_linuxC++之_类的继承定义
(一)访问控制和继承 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基 ...
- 实体类 @TableName&@TableField&@Version
//指向表table_biao @TableName("table_biao)public class UserThirdLogin extends Model<UserThirdLo ...
- Leetcode题目46.全排列(回溯+深度优先遍历+状态重置-中等)
题目描述: 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], ...
- Netfilter 之 iptable_filter
概述 本文主要对filter表的初始化流程,以及钩子函数的规则match流程的源码进行分析: 源码分析 所在钩子点: /* 在LOCAL_IN,FORWARD, LOCAL_OUT钩子点工作 */ # ...