声明:迁移自本人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数据的更多相关文章

  1. JNI的第2种写法:本地方法注册

    声明:迁移自本人CSDN博客https://blog.csdn.net/u013365635 孔乙己说,茴香豆的茴有四种写法,今天谈谈JNI的第2种写法:本地方法注册. 这种写法的好处是不需要使用ja ...

  2. 实现JNI的另一种方法:使用RegisterNatives方法传递和使用Java自定义类 (转)

    原帖地址:http://blog.csdn.net/qiuxiaolong007/article/details/7860610 除了使用传统方法实现JNI外,也可以使用RegisterNatives ...

  3. Java JNI 编程进阶 实例+c++数据类型与jni数据类型转换

    原文:http://www.iteye.com/topic/295776 JNI一直以来都很少去关注,但却是我心中的一个结,最近这几天刚好手头有点时间,因此抽空看了一下这方面的东西,整理了一份文档,J ...

  4. JNI/NDK开发指南(一)—— JNI开发流程及HelloWorld

    转载请注明出处:http://blog.csdn.net/xyang81/article/details/41777471 JNI全称是Java Native Interface(Java本地接口)单 ...

  5. JNI/NDK开发指南(十)——JNI局部引用、全局引用和弱全局引用

    转自:http://blog.csdn.net/xyang81/article/details/44657385   这篇文章比较偏理论,详细介绍了在编写本地代码时三种引用的使用场景和注意事项.可能看 ...

  6. JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系

    转载请注明出处:http://blog.csdn.net/xyang81/article/details/42047899 当我们在调用一个Java native方法的时候.方法中的參数是怎样传递给C ...

  7. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  8. javascript函数的几种写法集合

    1.常规写法 function fnName(){ console.log("常规写法"); } 2.匿名函数,函数保存到变量里 var myfn = function(){ co ...

  9. php插入式排序的两种写法。

    百度了下插入式排序,百度百科中php版本的插入式排序如下: function insert_sort($arr) { // 将$arr升序排列 $count = count($arr); for ($ ...

随机推荐

  1. cf754 754D - Fedor and coupons

    2个多小时,弱智了..(连A都做不对,就不要做D了(迷)) #include<bits/stdc++.h> #define lowbit(x) x&(-x) #define LL ...

  2. MESI缓存一致性协议

    整理一下一些计算机的基础概念. 概念 MESI(Modified, Exclusive, Shared, Invalid) 也称 Illinois 协议, 由美帝UIUC(University of ...

  3. 实验吧-隐写术-九连环(steghide)

    下载图片: 拿到kali里binwalk发现有压缩文件,然后foremost分解出来,将分出的压缩文件打开,发现已经被加密. 到这里就有几个思路了:1)暴力破解 2)伪加密 3)继续从图片中寻找信息 ...

  4. JavaScript的函数和对象介绍

    一.JavaScript中的函数 1.函数的概述 JavaScript中的函数是一段可执行代码的合集,在需要执行的时候可以在方法名之后添加一对小括号执行方法.是一段可执行的字符串. 2.函数中隐藏的属 ...

  5. PGSQL基本操作语句

    ; --更新数据 ,,) ; --插入数据 ORDER BY app_name,flag asc/desc ; --查询数据并且排序 offset ; --查询起点0开始查询,返回5条数据 ORDER ...

  6. (排序EX)P1583 魔法照片

    题解: 需要注意的是,快排完之后并不是按照编号从小到大的顺序输出 #include<iostream>using namespace std;int r=0;void swap(int & ...

  7. 2016蓝桥杯省赛C/C++A组第九题 密码脱落

    题意: X星球的考古学家发现了一批古代留下来的密码. 这些密码是由A.B.C.D 四种植物的种子串成的序列. 仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串). 由于年代久远,其中 ...

  8. 每天一点点之vue框架开发 - vue坑-input 的checked渲染问题

    选中radio或者checkbox需要注意的是: 不管<input type='radio checked='true''>  你的checked属性值是true或者false,他都会选中 ...

  9. 本地登录ftp的时候报530错误

    root@instance-iyi104bj:~# ftp localhost Connected to localhost. (vsFTPd ) Name (localhost:root): roo ...

  10. ORACLE异库DBLink创建以及使用

    遇到一个问题,两张库数据需要同步,但是数据量很大,落地迁移时间成本太大,这个时候找到一种方法就是DBLink 使用场景说明: A转移数据到B,需要在B上面创建此DBLink,然后使用. 创建方法: - ...