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 ($ ...
随机推荐
- cf754 754D - Fedor and coupons
2个多小时,弱智了..(连A都做不对,就不要做D了(迷)) #include<bits/stdc++.h> #define lowbit(x) x&(-x) #define LL ...
- MESI缓存一致性协议
整理一下一些计算机的基础概念. 概念 MESI(Modified, Exclusive, Shared, Invalid) 也称 Illinois 协议, 由美帝UIUC(University of ...
- 实验吧-隐写术-九连环(steghide)
下载图片: 拿到kali里binwalk发现有压缩文件,然后foremost分解出来,将分出的压缩文件打开,发现已经被加密. 到这里就有几个思路了:1)暴力破解 2)伪加密 3)继续从图片中寻找信息 ...
- JavaScript的函数和对象介绍
一.JavaScript中的函数 1.函数的概述 JavaScript中的函数是一段可执行代码的合集,在需要执行的时候可以在方法名之后添加一对小括号执行方法.是一段可执行的字符串. 2.函数中隐藏的属 ...
- PGSQL基本操作语句
; --更新数据 ,,) ; --插入数据 ORDER BY app_name,flag asc/desc ; --查询数据并且排序 offset ; --查询起点0开始查询,返回5条数据 ORDER ...
- (排序EX)P1583 魔法照片
题解: 需要注意的是,快排完之后并不是按照编号从小到大的顺序输出 #include<iostream>using namespace std;int r=0;void swap(int & ...
- 2016蓝桥杯省赛C/C++A组第九题 密码脱落
题意: X星球的考古学家发现了一批古代留下来的密码. 这些密码是由A.B.C.D 四种植物的种子串成的序列. 仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串). 由于年代久远,其中 ...
- 每天一点点之vue框架开发 - vue坑-input 的checked渲染问题
选中radio或者checkbox需要注意的是: 不管<input type='radio checked='true''> 你的checked属性值是true或者false,他都会选中 ...
- 本地登录ftp的时候报530错误
root@instance-iyi104bj:~# ftp localhost Connected to localhost. (vsFTPd ) Name (localhost:root): roo ...
- ORACLE异库DBLink创建以及使用
遇到一个问题,两张库数据需要同步,但是数据量很大,落地迁移时间成本太大,这个时候找到一种方法就是DBLink 使用场景说明: A转移数据到B,需要在B上面创建此DBLink,然后使用. 创建方法: - ...