JNI的第1种写法 及 JNI通过形参修改Java数据
声明:迁移自本人CSDN博客https://blog.csdn.net/u013365635
目的:通过形参在Java 和C之间传递数据,尤其是大块的媒体数据
优点:避免通过返回值返回一个巨大的数据块
声明:下文的大量操作作者是为了在一个目录下完成全部动作适配的,你大可以有更好的做法。文中涉及的目录参考者根据自己需要修改。重点是介绍一个完整可用的例子。
Step1:Java源码:
package com.testjni;
public class TestJNI
{
public native void tranferBytes(byte[] dataFromNative);
static
{
// 装入动态链接库
System.load("D:\\eclipseWebWorkSpace\\testest\\src\\com\\testjni\\libTestJNI_amd64.dll");
}
public static void main(String[] args)
{
TestJNI testJNI = new TestJNI();
// byte[] dataFromNative既是java传递给本地方法的参数,也是希望本地方法修改的参数
byte[] dataFromNative = new byte[10];
System.out.println("before-->dataFromNative=" + dataFromNative);
for (int i = 0; i < 10; i++)
{
System.out.print(dataFromNative[i] + " ");
}
System.out.println("\n----------");
testJNI.tranferBytes(dataFromNative);
System.out.println("after-->dataFromNative=" + dataFromNative);
for (int i = 0; i < 10; i++)
{
System.out.print(dataFromNative[i] + " ");
}
}
}
Step2:生成java类
javah -classpath D:\eclipseWebWorkSpace\testest\src com.testjni.TestJNI
Step3:生成jni头文件
javah -classpath D:\eclipseWebWorkSpace\testest\src com.testjni.TestJNI
生成的头文件如下。注意extern “C” {这个不能删除,否则C++的Name Mangling起作用运行时就无法找到自己写的函数了。
/* DO NOT EDIT THIS FILE - it is machine generated */
/*为了编译方便,把原本生成的#include <jni.h>改成了#include "jni.h"*/
#include "jni.h
/* Header for class com_testjni_TestJNI */
#ifndef _Included_com_testjni_TestJNI
#define _Included_com_testjni_TestJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_testjni_TestJNI
* Method: tranferBytes
* Signature: ([B)V
*/
JNIEXPORT void JNICALL Java_com_testjni_TestJNI_tranferBytes
(JNIEnv *, jobject, jbyteArray);
#ifdef __cplusplus
}
#endif
#endif
Step4:编写C++源文件
#include "com_testjni_TestJNI.h"
JNIEXPORT void JNICALL Java_com_testjni_TestJNI_tranferBytes(JNIEnv *jniEnv, jobject obj, jbyteArray dataFromNative)
{
jbyte* p = jniEnv->GetByteArrayElements(dataFromNative, NULL);
//这个地方就可以根据业务需要修改java传入的形参的值
for (int i = 0; i < 10; i++)
{
p[i] = i;
}
jniEnv->ReleaseByteArrayElements(dataFromNative, p, 0);
return;
}
此时你的目录大概长这个样子
很遗憾,此时执行
cl/LD D:\eclipseWebWorkSpace\testest\src\com\testjni\com_testjni_TestJNI.cpp -o D:\eclipseWebWorkSpace\testest\src\com\testjni\libTestJNI_amd64.dll
是编译不过的,你还需要以下2个头文件的支持:
C:\Program Files\Java\jdk1.8.0_144\include\jni.h和
C:\Program Files\Java\jdk1.8.0_144\include\win32\jni_md.h
Step5:把这2个头文件拷贝到当前目录D:\eclipseWebWorkSpace\testest\src\com\testjni
Step6:如果jdk是64位的,需要打开Visual Studio x64 Cross Tools Command Prompt而不是那个32位的。
然后执行cl /LD D:\eclipseWebWorkSpace\testest\src\com\testjni\com_testjni_TestJNI.cpp -o D:\eclipseWebWorkSpace\testest\src\com\testjni\libTestJNI_amd64.dll
好,现在你的目录大概长这样
当然了,以上除了libTestJNI_amd64.dll外,其他2个都是副产品,不是必须的,可以删除了。
此时再去跑跑java 代码,输出
before–>dataFromNative=[B@15db9742
0 0 0 0 0 0 0 0 0 0
after–>dataFromNative=[B@15db9742
0 1 2 3 4 5 6 7 8 9
JNI的第1种写法 及 JNI通过形参修改Java数据的更多相关文章
- JNI的第2种写法:本地方法注册
声明:迁移自本人CSDN博客https://blog.csdn.net/u013365635 孔乙己说,茴香豆的茴有四种写法,今天谈谈JNI的第2种写法:本地方法注册. 这种写法的好处是不需要使用ja ...
- 实现JNI的另一种方法:使用RegisterNatives方法传递和使用Java自定义类 (转)
原帖地址:http://blog.csdn.net/qiuxiaolong007/article/details/7860610 除了使用传统方法实现JNI外,也可以使用RegisterNatives ...
- Java JNI 编程进阶 实例+c++数据类型与jni数据类型转换
原文:http://www.iteye.com/topic/295776 JNI一直以来都很少去关注,但却是我心中的一个结,最近这几天刚好手头有点时间,因此抽空看了一下这方面的东西,整理了一份文档,J ...
- JNI/NDK开发指南(一)—— JNI开发流程及HelloWorld
转载请注明出处:http://blog.csdn.net/xyang81/article/details/41777471 JNI全称是Java Native Interface(Java本地接口)单 ...
- JNI/NDK开发指南(十)——JNI局部引用、全局引用和弱全局引用
转自:http://blog.csdn.net/xyang81/article/details/44657385 这篇文章比较偏理论,详细介绍了在编写本地代码时三种引用的使用场景和注意事项.可能看 ...
- JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
转载请注明出处:http://blog.csdn.net/xyang81/article/details/42047899 当我们在调用一个Java native方法的时候.方法中的參数是怎样传递给C ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- javascript函数的几种写法集合
1.常规写法 function fnName(){ console.log("常规写法"); } 2.匿名函数,函数保存到变量里 var myfn = function(){ co ...
- php插入式排序的两种写法。
百度了下插入式排序,百度百科中php版本的插入式排序如下: function insert_sort($arr) { // 将$arr升序排列 $count = count($arr); for ($ ...
随机推荐
- spring boot 使用swagger
在pom.xml中添加maven依赖 <dependency> <groupId>io.springfox</groupId> <artifactId> ...
- Web安全测试学习笔记 - vulhub环境搭建
Vulhub和DVWA一样,也是开源漏洞靶场,地址:https://github.com/vulhub/vulhub 环境搭建过程如下: 1. 下载和安装Ubuntu 16.04镜像,镜像地址:htt ...
- servlet中urlpatterns注意事项
在servlet中, @WebServlet(urlPatterns="/newsAdd")接收 resp.sendRedirect("/wedding/houtai/N ...
- oracle学习笔记(4)
4.oracle数据库的启动流程 windows操作系统 启动监听: lsnrctl start; 启动数据库实例:oradim-startup-sid 实例名 linux系统 启动监听:lsnrct ...
- Codeforces 460C 二分结果+线段树维护
发现最近碰到好多次二分结果的题目,上次多校也是,被我很机智的快速过了,这个思想确实非常不错.在正面求比较难处理的时候,二分结果再判断是否有效往往柳暗花明. 这个题目给定n个数字的序列,可以操作m次,每 ...
- 干货分享:Academic Essay写作套路详解
你想过如何中立的表达自己吗?大概只有10%不到的同学,会真正重视这个细节.但很多留学生能顺利写完作文已经不容易,还要注意什么中立不中立的.我知道这个标准,对许多同学有些过分,但很残酷的告诉你,这的确是 ...
- Object.keys(),Object.values(),Object.entries()
(1)Object.keys() // 返回数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名. eg:var obj = {a:1,b:'gy'} Ob ...
- leetcode 正则表达式 (动态规划)
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符'*' 匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串 s的 ...
- UVA - 11134 Fabled Rooks(传说中的车)(贪心)
题意:在n*n的棋盘上放n个车,使得任意两个车不相互攻击,且第i个车在一个给定的矩形Ri之内,不相互攻击是指不同行不同列,无解输出IMPOSSIBLE,否则分别输出第1,2,……,n个车的坐标. 分析 ...
- windows driver 映射大文件
//如果要做到掉电后仍然可以继续向下操作,可以记录文件的位置重新映射 NTSTATUS status; UNICODE_STRING strFileSrc = RTL_CONSTANT_STRING( ...