入门JNI需要知道的(二)

承接上篇

我们还需要知道更多关于c语言的一些知识.

  • c语言中的字符串.
    1. c语言中用字符数组保存字符串,但需要在最后保存一个结束标志 ‘\0’.所以有效字符会比字符数组实际长度少1.
    2. c语言中的字符串由string库函数处理,需要< string.h > 声明.
    3. strlen(一个参数) 计算字符串的长度 .
    4. strcmp(两个参数) 比较字符串.
    5. 注意:
      • 字符串长度不一定是数组容量-1.
      • 字符串长度,不包括空字符.
      • 字符串的比较:逐个字符比较,直到出现字符不相等.
  • 了解堆区内存
    下图大致表示了一个进程的内存分布
    进程的内存分布
  • 堆区内存使用malloc/free

    #include <stdio.h>
    #include <stdlib.h> // malloc() free()
    
    int main(){
            int num = 0;
            int i = 0;
    
            printf("输入数组长度: ");
            scanf("%d",&num);
    
            printf("num = %d\n",num);
    
            // int a[5]
            //空间大小 : num * sizeof(int)
            //数组名:int * 
    
            int *ptr = (int *)malloc(num * sizeof(int)); //malloc是一个指针函数 , 后面会讲到
    
            for(i = 0;i < num;i++){     
                printf("输入第%d个元素的值: ",i+1);
                scanf("%d",ptr + i);    //等价于scanf("%d",&ptr[i]);
                //但是不能使用 scanf("%d",ptr++); 因为ptr自增之后,free(ptr)中的 ptr已经不是原来的ptr了 
            }
    
            for(i = 0;i < num;i++){
                printf("id[%d] = %d\n",i,ptr[i]);
            }
    
            free(ptr);//释放ptr指向的堆区空间 
            ptr = NULL;
    
            return 0;
    } 
    
  • c语言中的结构体
    相当于java中的没有方法的对象,只有变量,但是可以通过函数指针变量指向一个函数.

    struct Student{
            char name[20];
            int age;
            float score;
        }s2;
    // struct Student 这里比较特殊,需要两个写在一起才算结构体类型名,和int * 有一点类似.
    //        Student 结构体名 
    
    int main(){
    
        struct Student s1; 
    
        struct Student *ptr = &s1;
        struct Student * *pp = &ptr;
    
        s1.age = 20;
    
        //*ptr <=> s1
        //(*ptr).age = 30;
        ptr->age = 40;//结构体指针访问其指向结构体变量中成员变量 
    
        //**pp <=> *ptr <=> s1
        (**pp).age = 50;
        (*pp)->age = 60;
    
        return 0;
    } 
    
  • 函数指针

    • 函数入口地址:函数保存在text代码段中起始位置, 函数名代表函数的入口地址
    • 函数指针:函数指针变量保存函数的入口地址。
    • 特别区分函数指针与指针函数.

      1. 函数指针指向函数, 返回值由函数决定 ,它是一个指针变量.
      2. 指针函数返回指针, 它是一个函数.

        int add(int a,int b){
            return a + b;
        }
        
        int sub(int a,int b){
            return a - b;
        }
        
        int calc(int a,int b,int (*pfun)(int,int)){
            return pfun(a,b);
        }
        
        int main(){
                //int (int,int) 函数类型  
                //函数指针变量名要定义在 函数名的位置上,并且用括号括起来 
            int (*ptr)(int,int) = add; //正确的 函数指针 变量 定义
            //int * ptr (int,int); 这是一个 指针函数,返回值类型是指针类型,不能混淆
            //为了方便记忆, 星被括号括起来, 一般情况就可以看作是函数指针, ptr就是函数指针的变量名
        
            int a = 10,b = 20;
            int result = 0;
        
            result = add(a,b);//直接调用
        
            printf("result = %d\n",result); 
        
            result = ptr(a,b);
            printf("result = %d\n",result); 
        
            result = calc(a,b,add);//函数的回调 
            printf("result = %d\n",result); 
        
            result = calc(a,b,sub);
            printf("result = %d\n",result); 
        
            return 0; 
        }
        
  • typedef
    给已经存在的数据类型起别名,需要特别注意的是结构体指针类型

    int a;//a是一个标识符,a是一个变量名
    typedef int a;//a是一个标识符,a成为int类型的别名
    
    struct Student{
        ...}s1; //s1是一个标符识,s1是一个变量名
    
    typedef struct Student{
        ...}s1; //s1是一个标符识,s1变成struct Student类型别名
    
    struct Student * pstu;//pstu是一个标符识,pstu是一个结构体指针变量名
    typedef struct Student * pstu;//pstu是一个标符识,pstu是一个结构体指针类型
    
    int (*pfun)(int,int *);//pfun是一个标识符,pfun是一个函数指针变量名
    
    typedef int (*pfun)(int,int *);// pfun <=> int (*)(int,int*)
    //pfun是一个标识符,pfun是一个函数指针类型, 是int (*)(int,int*)的别名
    
  • jni头文件

    • 在了解了typedef 之后, 我们就可以看懂SDK里面的jni.h头文件了. D:\SDK\ndk-bundle\platforms\android-19\arch-arm\usr\include
      jni的头文件信息
    • jni.h头文件的作用
      • 要实现java调用c 代码, 无非就是数据的传递, 数据要传递, 那么数据类型就一定要对应起来, 相同类型的数据可以直接传递, 不同类型则需要利用函数转换. 例如
        jni头文件
        这个函数指针指向的 函数的作用就是让c里面的char * 字符串转换成java里面的jstring对象.
      • 所以, jni头文件无非就是提供给我们在JNI编程时, c 代码数据传给java ,java 代码数据传给 c 的过程中, 如果数据类型不匹配, 就需要它里面的函数进行数据的转换.
  • jni头文件里重要的结构体

    • jni头文件里有很多结构体指针类型
      这里写图片描述

      typedef struct JNINativeInterface* JNIEnv;
      
      JNIEnv <=> struct JNINativeInterface*
      
      JNIEnv * 是什么呢?
      
      JNIEnv * env; 是我们实际需要用到的参数.
      
      env : JNIEnv * <=> struct JNINativeInterface* *
      env本质上是一个二级结构体指针,若真正要访问struct JNINativeInterface*结构体中的成员,按照如下写法
      
      (**env).FindClass();
      通常按照下面的写法:
      (*env)->FindClass();
      

JNI涉及概念

  • 交叉编译: 一个平台(操作系统或处理器架构)为另一个平台编译代码.
    区别本地编译
  • 工具链: 一套编译工具,编译过程中顺序调用的一套工具.
  • 函数库: 实现某一类功能函数的集合,其中的代码已经编译成了二进制机器指令(c中非系统函数库需要我们手动链接). 提供库至少需要提供两个文件,.h头文件声明库中的函数和.so/.a库文件包含函数的具体实现.
  • 静态链接库 .a 静态库只用在静态链接过程中,将库的二进制机器指令拷贝一份.
  • 动态链接库(共享库) .so 动态库先用在动态链接过程中,记录用到哪个库的哪个函数.在程序运行之前,需要先加载动态库.

JNI开发相关工具

  • NDK: Native Development kit 本地开发工具集
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
【5层】公司办公楼全套设计+++(3156平,含计算书、建筑图,结构图、实习报告,PKPM,答辩PPT) 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值