zoukankan      html  css  js  c++  java
  • 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("
    ----------");
            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 estestsrc com.testjni.TestJNI
    Step3:生成jni头文件
    javah -classpath D:eclipseWebWorkSpace estestsrc 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 estestsrccom estjnicom_testjni_TestJNI.cpp -o D:eclipseWebWorkSpace estestsrccom estjnilibTestJNI_amd64.dll
    是编译不过的,你还需要以下2个头文件的支持:
    C:Program FilesJavajdk1.8.0_144includejni.h和
    C:Program FilesJavajdk1.8.0_144includewin32jni_md.h
    Step5:把这2个头文件拷贝到当前目录D:eclipseWebWorkSpace estestsrccom estjni
    Step6:如果jdk是64位的,需要打开Visual Studio x64 Cross Tools Command Prompt而不是那个32位的。
    然后执行cl /LD D:eclipseWebWorkSpace estestsrccom estjnicom_testjni_TestJNI.cpp -o D:eclipseWebWorkSpace estestsrccom estjnilibTestJNI_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

  • 相关阅读:
    whith ~ as 用法
    python函数 传参的多种方式 解读
    关于HTTP协议,一篇就够了
    appium+python自动化 adb shell按键操作
    貌似这个官网有api按,有空研究下
    切换了webview 定位不了的解决方法 (还没有试,记录在此)
    补充appium -api
    appium 点击物理按键
    修改最后一次 已commit 的备注
    场景记录
  • 原文地址:https://www.cnblogs.com/xsl-thumb-rfcs/p/9941605.html
Copyright © 2011-2022 走看看