JNI/NDK开发指南(十一)——JNI异常处理

NDK-异常处理与动态注册 如果native方法不需要JNIEnv、jclass/jobject,那么也可以直接不写。如下所示// 也OK 如果你用不到 JNIEnv jobject ,可以不用写 void dynamicMethod01() {LOGD("我是动态注册的函数 dynamicMethod01...");// 也OK const char * text = env -> GetStringUTFChars(valueStr , nullptr);... 阅读详情

转自:http://blog.youkuaiyun.com/xyang81/article/details/45770551

异常简介

异常,显而意见就是程序在运行期间没有按照正常的程序逻辑执行,在执行过程当中出现了某种错误,导致程序崩溃。在Java中异常分为运行时异常(RuntimeException)和编译时异常,在程序中有可能运行期间发生异常的逻辑我们会用try…catch…来处理,如果没有处理的话,在运行期间发生异常就会导致程序奔溃。而编译时异常是在编译期间就必须处理的。本章主要介绍运行时异常。 
示例1:

// 运行时异常
public static void exceptionCallback() {
    int a = 20 / 0;
    System.out.println("--->" + a);
}
 
  • 1
  • 2
  • 3
  • 4
  • 5

示例2:

// 编译期间异常
public static void testException() throws Exception {
    // ...
    System.out.println("testException() invoked!");
}
public static void main(String[] args) {
    exceptionCallback(); 
    try {
        testException();
    } catch (Exception e) {
        e.printStackTrace();
    }
    // ....
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
在示例2中,testException方法声明时显示抛出了一个java.lang.Exception异常,所以在程序调用的地方必须用try...catch处理。

 
  • 1
  • 2

大家都知道,如果示例2中main方法执行到调用exceptionCallback方法时,方法第一行有一个除0的操作,因此该方法会抛出java.lang.ArithmeticException数学异常,而在main方法调用的时候并没有处理这个函数在运行时可能会发生的异常,所以会导致程序立即结束,而后面的代码try{testException();}catch(Exception e) {e.printStackTrace();}都不会被执行。运行示例2程序的你会看到下面的结果:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at com.study.jnilearn.JNIException.exceptionCallback(JNIException.java:8)
    at com.study.jnilearn.JNIException.main(JNIException.java:22)
 
  • 1
  • 2
  • 3

我们改进一下上面这个程序:

public static void main(String[] args) {
    try {
        exceptionCallback();
    } catch (Exception e) {
        e.printStackTrace();
    }

    try {
        testException();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这时我们运行程序,调用exceptionCallback方法时会引发java.lang.ArithmeticException: / by zero异常,由于我们用try…catch块显示处理了异常,所以程序会继续往下执行,调用testException()函数,打印testException() invoked!。运行结果如下所示:

java.lang.ArithmeticException: / by zero
    at com.study.jnilearn.JNIException.exceptionCallback(JNIException.java:8)
    at com.study.jnilearn.JNIException.main(JNIException.java:24)
testException() invoked!
 
  • 1
  • 2
  • 3
  • 4

Java与JNI处理异常的区别

下面来小结一下: 
1、在Java中如果觉得某段逻辑可能会引发异常,用try…catch机制来捕获并处理异常即可 
2、如果在Java中发生运行时异常,没有使用try…catch来捕获,会导致程序直接奔溃退出,后续的代码都不会被执行 
3、编译时异常,是在方法声明时显示用throw声明了某一个异常,编译器要求在调用的时候必须显示捕获处理 
public static void testException() throws Exception {} 
上面这几点,写过Java的朋友都知道,而且很简单,但我为什么还要拿出来说呢,其实我想重点说明的是,在JNI中发生的异常和Java完全不一样。我们在写JNI程序的时候,JNI没有像Java一样有try…catch…final这样的异常处理机制,面且在本地代码中调用某个JNI接口时如果发生了异常,后续的本地代码不会立即停止执行,而会继续往下执行后面的代码。

异常处理示例

示例3: 
这个例子在main中调用了doit本地方法,在本地方法中会回调exceptionCallback方法,该方法中会引发一个除0的运行时异常java.lang.ArithmeticException,我们通过这个示例来学习在JNI中如何来正确处理这种异常。

package com.study.jnilearn;

public class JNIException {

    public static native void doit();

    public static void exceptionCallback() {
        int a = 20 / 0;
        System.out.println("--->" + a);
    }

    public static void normalCallback() {
        System.out.println("In Java: invoke normalCallback.");
    }

    public static void main(String[] args) {
        doit();
    }

    static {
        System.loadLibrary("JNIException");
    }
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_study_jnilearn_JNIException */

#ifndef _Included_com_study_jnilearn_JNIException
#define _Included_com_study_jnilearn_JNIException
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_study_jnilearn_JNIException
 * Method:    doit
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_study_jnilearn_JNIException_doit
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

// JNIException.c
#include "com_study_jnilearn_JNIException.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_com_study_jnilearn_JNIException_doit(JNIEnv *env, jclass cls) {
    jthrowable exc = NULL;
    jmethodID mid = (*env)->GetStaticMethodID(env,cls,"exceptionCallback","()V");
    if (mid != NULL) {
        (*env)->CallStaticVoidMethod(env,cls,mid);
    }
    printf("In C: Java_com_study_jnilearn_JNIException_doit-->called!!!!");
    if ((*env)->ExceptionCheck(env)) {  // 检查JNI调用是否有引发异常
        (*env)->ExceptionDescribe(env);
        (*env)->ExceptionClear(env);        // 清除引发的异常,在Java层不会打印异常的堆栈信息
        (*env)->ThrowNew(env,(*env)->FindClass(env,"java/lang/Exception"),"JNI抛出的异常!");
        //return;
    }
    mid = (*env)->GetStaticMethodID(env,cls,"normalCallback","()V");
    if (mid != NULL) {
        (*env)->CallStaticVoidMethod(env,cls,mid);
    }
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

程序运行结果如下:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at com.study.jnilearn.JNIException.exceptionCallback(JNIException.java:8)
    at com.study.jnilearn.JNIException.doit(Native Method)
    at com.study.jnilearn.JNIException.main(JNIException.java:17)
Exception in thread "main" java.lang.Exception: JNI抛出的异常!
    at com.study.jnilearn.JNIException.doit(Native Method)

In Java: invoke normalCallback.
    at com.study.jnilearn.JNIException.main(JNIException.java:17)
In C: Java_com_study_jnilearn_JNIException_doit-->called!!!!
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在Main方法中调用doit本地方法后,程序的控制权即交给了JNI,在doit的本地方法中回调exceptionCallback方法,引发了一个java.lang.ArithmeticException异常,但本地接口并不会马上退出,而是会继续执行后面的代码,所以我们在调用完一个任何一个JNI接口之后,必须要做的一件事情就是检查这次JNI调用是否发生了异常,如果发生了异常不处理,而继续让程序执行后面的逻辑,将会产生不可预知的后果。在本例中,我们调用了JNI的ExceptionCheck函数检查最近一次JNi调用是否发生了异常,如果有异常这个函数返回JNI_TRUE,否则返回JNI_FALSE。当检测到异常时,我们调用ExceptionDescribe函数打印这个异常的堆栈信息,然后再调用ExceptionClear函数清除异常堆栈信息的缓冲区(如果不清除,后面调用ThrowNew抛出的异常堆栈信息会覆盖前面的异常信息),最后调用ThrowNew函数手动抛出一个java.lang.Exception异常。但在JNI中抛出未捕获的异常与Java的异常处理机制不一样,在JNI中并不会立即终止本地方法的执行,而是继续执行后面的代码。这种情况需要我们手动来处理。在例中的38行,如果你不用return马上退出方法的话,37行ThrowNew后面的代码依然会继续执行,如程序运行的结果一样,仍然会回调normalCallback方法,打印出:invoke normalCallback. 
异常检查JNI还提供了另外一个接口,ExceptionOccurred,如果检测有异常发生时,该函数会返回一个指向当前异常的引用。作用和ExceptionCheck一样,两者的区别在于返回值不一样。我们改造一下上面的例子:

// ....
jthrowable exc = NULL;
exc = (*env)->ExceptionOccurred(env);  // 返回一个指向当前异常对象的引用
if (exc) {
    (*env)->ExceptionDescribe(env); // 打印Java层抛出的异常堆栈信息
    (*env)->ExceptionClear(env);        // 清除异常信息

    // 抛出我们自己的异常处理
    jclass newExcCls;
    newExcCls = (*env)->FindClass(env,"java/lang/Exception");
    if (newExcCls == NULL) {
        return;
    }
    (*env)->ThrowNew(env, newExcCls, "throw from C Code.");
}

// ....
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

写一个抛出异常的工具类

当需要抛出自己的异常处理逻辑时,需要二步,调用FindClass找到异常处理类,然后调用ThrowNew抛出一个异常。为了简化操作步聚,我们写一个工具函数,根据一个异常类名专门用来生成一个指定名字的异常:

void JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg)
 {
     // 查找异常类
     jclass cls = (*env)->FindClass(env, name);
     /* 如果这个异常类没有找到,VM会抛出一个NowClassDefFoundError异常 */
     if (cls != NULL) {
         (*env)->ThrowNew(env, cls, msg);  // 抛出指定名字的异常
     }
     /* 释放局部引用 */
     (*env)->DeleteLocalRef(env, cls);
 }
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

异常发生后释放资源

在异常发生后,释放资源是一件很重要的事情。下面的例子中,调用 GetStringChars 函数后,如果后面的代码发生异常,要记得调用 ReleaseStringChars 释放资源。

JNIEXPORT void JNICALL Java_pkg_Cls_f(JNIEnv *env, jclass cls, jstring jstr)
 {
     const jchar *cstr = (*env)->GetStringChars(env, jstr);
     if (c_str == NULL) {
         return; 
     }
     ...
     if ((*env)->ExceptionCheck(env)) { /* 异常检查 */
         (*env)->ReleaseStringChars(env, jstr, cstr); // 发生异常后释放前面所分配的内存
         return; 
     }
     ...
     /* 正常返回 */
     (*env)->ReleaseStringChars(env, jstr, cstr);
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

总结

1、当调用一个JNI函数后,必须先检查、处理、清除异常后再做其它 JNI 函数调用,否则会产生不可预知的结果。 
2、一旦发生异常,立即返回,让调用者处理这个异常。或 调用 ExceptionClear 清除异常,然后执行自己的异常处理代码。 
3、异常处理的相关JNI函数总结: 
1> ExceptionCheck:检查是否发生了异常,若有异常返回JNI_TRUE,否则返回JNI_FALSE 
2> ExceptionOccurred:检查是否发生了异常,若用异常返回该异常的引用,否则返回NULL 
3> ExceptionDescribe:打印异常的堆栈信息 
4> ExceptionClear:清除异常堆栈信息 
5> ThrowNew:在当前线程触发一个异常,并自定义输出异常信息 
jint (JNICALL *ThrowNew) (JNIEnv *env, jclass clazz, const char *msg); 
6> Throw:丢弃一个现有的异常对象,在当前线程触发一个新的异常 
jint (JNICALL *Throw) (JNIEnv *env, jthrowable obj); 
7> FatalError:致命异常,用于输出一个异常信息,并终止当前VM实例(即退出程序) 
void (JNICALL *FatalError) (JNIEnv *env, const char *msg);

Android NDK开发之旅(2):Android Studio中使用CMake进行NDK/JNI开发(初级) CMake是一款比make更强大的编译自动配置工具,它可以根据不同平台、不同的编译器,并通过CMakeLists.txt文件中简单的语句来描述所有平台的编译过程,生成相应的Makefile文件或project文件。CMake被引入于AndroidStudio2.2,其目的是替代原有的JNI/DNK开发方法,使AS在进行JNI/NDK时更加的方便、高效。CMake的优势如下: (1) 允许直接在C/C++代码中加入断点,调试; (2) 在Java层中使用“ctrl+左键”快捷键能够直接进入本地方法对应 阅读详情

相关推荐

Android Studio中NDK与JNI开发入门指南

Java Native Interface (JNI) 是一个编程框架,允许Java代码和其他语言写的代码(主要是C和C++)进行交互。其定义了一个标准的编程接口,使得Java虚拟机(JVM)中的Java代码能够调用本地应用程序接口(API)中的本地方法(用C、C++或其他语言实现的方法),以及反过来实现本地方法调用Java对象和其方法。JNI不仅提供了一种机制来调用本地方法,同时也需要一种方式来处理不同数据类型之间的转换。

weixin_32099703的博客 1310

JNI/NDK入门指南之JNI异常处理

          JNI/NDK入门指南之JNI异常处理   任何人都犯错误,连我们的好人强东哥都是如此,当然我们程序员也在这个行列之内了,哈哈(不是各位读者想象的那个错啊)。在Java ...

IT先森 2889

Unity Animancer插件(一)基本使用

Animancer是什么?资源商店主页我们来通过Animancer实现一个最基本的动画播放效果。首先创建一个脚本,编写如下代码 很容易理解,就是在时播放一个指定的动画片段。接下来为角色添加、和刚刚编写的,并为字段赋值 接下来运行游戏就可以看到效果了 此时角色身上的组件可以看到当前动画的各项参数 下面我们来实现通过按键控制角色在于之间转换。新创建一个脚本。在代码中监听Y轴上的输入。然后根据监听到的数值判断角色状态,并播放相应的动画 给对应字段赋值后,启动游戏看下效果 下面来实现一个开枪效果。在默认状态下,角色

夜槿笙歌的博客 1万+

JNI各种异常分析

今天Android123主要讲解下昨天需要详细说明有关Java JNI相关的异常处理、线程安全问题,在JNI中产生的异常主要是内存不足OutOfMemoryError、数组越界ArrayIndexOutOfBoundsException、数组赋值类型错误ArrayStoreException以及指针越界等问题。简单的我们昨天在 Android JNI开发提高篇中已经讲到。   除了Throw或T

ljwshi2008的专栏 1451

秋叶ComfyUI整合包:一键部署AI绘画工作流,解决环境配置难题

在AI绘画和生成式AI领域,Stable Diffusion作为开源的扩散模型,为图像生成提供了强大的技术基础。其核心原理是通过学习数据分布,对随机噪声进行逐步去噪,最终生成高质量的图像。这项技术的价值在于极大地降低了专业图像创作的门槛,并推动了AIGC(人工智能生成内容)在艺术设计、游戏开发、广告营销等场景的广泛应用。然而,其典型工作流实现工具ComfyUI,在实际部署中常因Python环境、PyTorch版本与CUDA驱动之间的复杂依赖关系而受阻,尤其是面对NVIDIA 30系、40系及未来50系等不同

优快云头条 669

LM358实战:手把手教你搭建电流检测电路(附电阻选型计算)

本文详细解析了使用LM358运算放大器搭建电流检测电路的全过程,包括基础原理、采样电阻选型、放大电路设计及PCB布局技巧。通过实战案例和精确计算,帮助工程师快速掌握低成本、高精度的电流检测方案,适用于电源管理、电机控制等多种应用场景。

weixin_30872157的博客 449

JNI/NDK入门指南之正确姿势了解JNI和NDK

         你真的了解Android中JNI/NDK吗?    随着Android生态的发展,越来越多的行业开始使用Android操作系统,这就造就了对Android设备的应用性能和安全要求越来越高,随之而来的对JNI/NDK开发的需求也越来越大。虽然网上或者很多书籍都有关于此方面的讲解,但是都是上来直奔主题说怎么使用JNI/NDK,而没有将啥是JNI和NDK讲解清楚。所以导致很...

IT先森 3570

最新Docker GPU支持全解析:为什么nvidia-smi能用但PyTorch找不到CUDA?

本文深入解析了Docker容器中nvidia-smi命令可用但PyTorch无法调用CUDA的根本原因。关键在于默认配置仅暴露了GPU的utility管理能力,而CUDA计算所需的compute能力未被激活。通过正确设置NVIDIA_DRIVER_CAPABILITIES环境变量为compute,utility,并配合--gpus参数,即可解决此问题,确保AI训练等任务顺利进行。

convnet3designer的博客 242

JNI/NDK入门指南之jobject和jclass

      JNI/NDK开发指南之jobject和jclass   在前面的章节JNI/NDK开发指南之JavaVM和JNIEnv中,我们详细介绍了一番JavaVM和JNIEnv,那么今天的篇章里面分别介绍一番jobject和jclass两个概念。 细说jobject和jclass 在JNI开发中JNI,实例引用(jobject)和类引用(jclass)让人觉得很困惑,至少我刚开始学习的时候...

IT先森 5417

【SpringBoot】1、创建第一个SpringBoot项目

创建SpringBoot项目可以通过两种方式,1、通过访问:https://start.spring.io/,SpringBoot的官方网站进行创建SpringBoot项目;2、通过工具(例如:Idea)创建SpringBoot项目。本次使用开发工具:Idea创建我的第一个SpringBoot项目。 首先,打开我们的Idea开发工具 选择Create New Poject(创建一个新的项目) ...

JACKAL 21万+

【报错解决】彻底解决 MySQL 登录报错 ERROR 1045 (28000)

MySQL 报错 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 通常是由于用户名或密码错误、权限不足、服务未启动或配置文件异常导致的。通过检查并确认密码、重置 root 用户密码、授予完整权限、校验配置文件以及确保 MySQL 服务正常运行,可以彻底解决该问题。掌握这一流程不仅能够恢复 root 登录,还能保障数据库的安全性与稳定性。

博客 1750

JNI/NDK入门指南之Eclipse集成NDK开发环境并使用

    JNI/NDK开发指南之Eclipse集成NDK开发环境并使用    在前面的章节里面,我们已经了解了JNI开发所需要掌握的相关基本知识。那么在本篇文章里面将要介绍Eclipse集成NDK开发环境。 配置使用步骤 这里我会以一个简单的Android中使用JNI开发的列子来说明,怎么在Eclipse中集成NDK开发环境并使用之。 1.Eclipse配置NDK开发环境 在前面的章...

IT先森 1275

E2B Agent Runtime Sandbox 沙箱技术架构研究

本实现指南基于E2B的技术架构,提供了完整的基于Firecracker和Docker的Agent Runtime Sandbox后端服务实现方案。架构设计:参考E2B的分层架构,实现API层、管理层和虚拟化层Firecracker集成:深度集成Firecracker提供硬件级安全隔离完整功能:支持文件读写、shell执行、浏览器访问等核心功能生产就绪:提供Docker部署、监控、测试和安全配置可扩展性:设计支持水平扩展和高并发场景。

AI天才研究院 749

JNI/NDK入门指南之开篇

           JNI/NDK入门指南之开篇   对于Android开发者,是否有过这么一个场景当你天天使用者Android SDK提供的API接口时,你会有好奇过Android底层是怎么实现的呢,可能当你翻阅Android源码时看到JNI看到C/C++就退缩了。对于Java开发者,是否想进一步利用本地语言的特色譬如C/C++。对于上述两种场景,那么JNI都是无法跨越的坎,在这个系列里面我...

IT先森 2638

uniapp:实现APP获取陀螺仪数据、加速传感器、线性加速传感器,uniApp实时监听陀螺仪【XYZ】数据及停止监听与资源释放等功能示例源码,根据需求做功能(完美兼容Android安卓、苹果ios)

uniapp陀螺仪,uniapp加速传感器,uniapp线性加速传感器,APP陀螺仪数据,uniapp app 端获取陀螺仪数据示例代码,手机中获取陀螺仪的数据,uniApp实时获取陀螺仪xyz数据,android陀螺仪方向,获得陀螺仪传感器,处理传感器数据,停止监听与资源释放,Android使用陀螺仪,uniapp苹果ios陀螺仪,uni-app设备之(加速计,罗盘,陀螺仪)插件安卓/IOS APP提供了获取陀螺仪数据的能力,手机陀螺仪传感器获得手机自身旋转的角度,陀螺仪获取旋转角度,陀螺仪、加速度传感器

✅ 精选推荐文章 4268

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

JNI/NDK入门指南之JNI访问数组

        JNI/NDK入门指南之JNI访问数组   在前面的章节JNI/NDK入门指南之JNI字符串处理中讲解了JNI对字符串的处理流程。今天我们继续向JNI的知识海洋进军讲解JNI对数组的处理。本章内容有点多哦! 前言 JNI 中的数组分为基本类型数组和对象数组,它们的处理方式是不一样的,基本类型数组中的所有元素都是 JNI的基本数据类型,可以直接访问。而对象数组中的所有元素...

IT先森 4581

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

JNI/NDK入门指南之JNI字符串处理

       JNI/NDK开发指南之JNI字符串处理   在前面的章节JNI/NDK开发指南之JNI数据类型,描述符详解中我们了解了JNI能处理的基本类型,细心的读者会发现这其中不包括字符串。那么今天我们要重点讲解的就是JNI中对字符串的处理了。 ...

IT先森 3204

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

JNI/NDK入门指南之javah和javap的使用和集成

     JNI/NDK开发指南之javah和javap的使用和集成   在前面的章节JNI/NDK开发指南之JNI数据类型,描述符详解中我们详细的讲解了数据类型,描述符等相关的概念。如果是刚开始接触JNI的话,读者看到那些概念都会懵逼了,哇开发一个JNI的端咋这么多需要记忆的概念,描述符啊,数据类型啊,签名啊?其实JDK的开发工具为我们提供了一些快捷的工具如javah和javap,这两个...

IT先森 2010
上一篇: Understanding Convolutional Neural Networks for NLP(理解自然语言处理中的卷积神经网络)
下一篇: How to train your Deep Neural Network(如何训练你的深度神经网络)
class_brick
博客等级 码龄12年 223粉丝 76原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值