声明:迁移自本人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. SLAM的评测工具evo

    遇到的问题 今天用orbslam2跑euroc数据集,将结果和真实轨迹用evo测评,发现差别特别大: evo_traj tum data.tum CameraTrajectory.txt --plot ...

  2. 029-PHP取随机数

    <?php //打印从1到100中间的10个随机的数 ; $index < ; $index++) { print(rand(,) . "<BR>\n"); ...

  3. 记--linux 下svn安装配置,同步web目录

    安装#yum install subversion 1.创建版本库 # svnadmin create /svn/project 2.配置svn服务的配置文件svnserver.conf文件 anon ...

  4. C#图片闪烁

    导致画面闪烁的关键原因分析:       一.绘制窗口由于大小位置状态改变进行重绘操作时      绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面重新刷新一次以维持窗 ...

  5. 事件时间(event time)与水印(watermark)

    事件时间和水印诞生的背景 在实际的流式计算中数据到来的顺序对计算结果的正确性有至关重要的影响 比如:某数据源中的某些数据由于某种原因(如:网络原因,外部存储自身原因)会有2秒的延时,也就是在实际时间的 ...

  6. MongoDB Limit

    版权所有,未经许可,禁止转载 章节 MongoDB 入门 MongoDB 优势 MongoDB 安装 MongoDB 数据建模 MongoDB 创建数据库 MongoDB 删除数据库 MongoDB ...

  7. (四)requests模块的cookies和代理操作

    基于requests模块的cookie操作 引言:有些时候,我们在使用爬虫程序去爬取一些用户相关信息的数据(爬取某个人“人人网”个人主页数据)时,如果使用之前requests模块常规操作时,往往达不到 ...

  8. elasticsearch下载与安装

    目录 安装之前 下载 安装 测试 安装之前 必须注意的是:安装路径不允许有中文及空格和非法字符,尤其是中文 下载 打开elasticsearch官网.选择免费试用. 选择对应产品与版本(选择6.5.4 ...

  9. 将已有微信小程序转换为多端应用

    文档地址 https://nervjs.github.io/taro/

  10. Adobe Photoshop CC2014 for MAC 详细破解步骤

    1,安装Adobe Photoshop CC2014 for MAC,可以断网安装,如果不断网的话,需要申请一个Adobe ID,是免费申请. 2,下载破解工具,https://sdifen.ctfi ...