Android——C语言、JNI与低层调用
JNI
java native interface
c的基本数据类型
- int:32位,能表示的数字是2的32次方个
- 最高位用来表示符号位,那么还剩下31位可以表示数值,所以能表示的数字就是2的31次方个
- int的表示范围:
- 当最高位是0时:0~2147483647
- 当最高位是1是:-2147483648~-1
java的基本数据类型长度
c的基本数据类型长度
- byte:1
- short:2
- int:4
- long:8
- boolean:1
- char:2
- float:4
- double:8
- short:2
- int:4
- long:4
- char:1
- float:4
- double:8
*的三种用法
- 乘法
- int* p: 定义一个指针变量p,p中存放一个内存地址,这个地址所存放的数据规定是int型
- *p: 取出p中保存的内存地址存放的数据
数据传递
- 所有语言所有平台,都只有值传递,引用传递 传递的值是内存地址
栈
- 系统自动分配和释放
- 保存全局、静态、局部变量
- 在栈上分配内存叫静态分配
- 大小一般是固定的
堆
- 程序员手动分配(malloc/new)和释放(free/java不用手动释放)
- 在堆上分配内存叫动态分配
- 一般硬件内存有多大就有多大
交叉编译
- 在一个平台下,编译出另一个平台能够执行的二进制的代码
- 平台:windows,mac os,linux
- 处理器:x86,arm,mips
交叉编译的原理
- 源代码->编译->链接->可执行程序
- 模拟其他平台的特性
交叉编译的工具链
- 多个工具的集合,一个工具使用完后接着调用下一个工具
常见工具
- NDK:native developement kit:开发jni必备,就是模拟其他平台特性来编译代码的工具
- CDT:C/C++ developement tools:高亮显示c语言关键字
- cygwin:一个模拟器,可以再windows下运行linux指令
NDK目录结构
- docs:帮助文档
- build/tools:linux的批处理文件
- platforms:编译c代码需要使用的头文件和类库
- prebuilt:预编译使用的二进制可执行文件
- sample:jni的使用例子
- source:ndk的源码
- toolchains:工具链
- ndk-build.cmd:编译打包c代码的一个指令
使用jni
- 在项目根目录下创建jni文件夹
- 在jni文件中创建一个c文件
在java代码中,创建一个本地方法helloFromC
public native String helloFromC();
在jni中定义函数实现这个方法,函数名必须为
jstring Java_com_example_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)
返回一个字符串,用c定义一个字符串
char* cstr = "hello from c";
把c的字符串转换成java的字符串
jstring jstr = (*env)->NewStringUTF(env, cstr);
return jstr;- 在jni中创建Android.mk文件
- 在c文件中添加<jni.h>头文件
- 在jni文件夹下执行ndk-build.cmd指令
- java代码中加载so类库,调用本地方法
常见错误
findLibrary returned null
- CPU平台不匹配
- 加载类库时,写错类库名字
本地方法找不到
- 忘记加载类库
- c代码中方法名写错了
javah
*1.7:在src目录下执行javah 包名.类名 *1.6:在bin/classes目录下执行
javap
- 在bin/class目录下执行javap -s 包名.类名
- 打印方法签名
C向C++改造
- 把c文件后缀名换成cpp
- Android.mk文件中的hello.c也要换成hello.cpp
- c++的使用的环境变量结构体中,访问了c使用的结构体的函数指针,函数名全部都是一样的,只是参数去掉了结构体指针
- 访问函数指针时,把env前面的*号去掉,因为此时env已经是一级指针
- clean,清除之前编译的残留文件
- 把声明函数的h文件放入jni文件夹中,include该h文件
Android——C语言、JNI与低层调用的更多相关文章
- Android项目中JNI技术生成并调用.so动态库实现详解
生成 jni方式有两种:一种是通过SWIG从C++代码生成过度的java代码:另一种是通过javah的方式从java代码自动生成过度的C++代码.两种方式下的步骤流程正好相反. 第一种方式:由于需要配 ...
- Android JNI之C/C++层调用JAVA
转载请声明:原文转自:http://www.cnblogs.com/xiezie/p/5930032.html 从C/C++层调用JAVA层代码步骤: 1. 在JAVA类中创建java方法和本地方法 ...
- Android JNI开发之C/C++层调用JAVA
一.从C/C++层调用JAVA层代码(无参数调用) //在c代码里面调用java代码里面的方法 // java 反射 // 1 . 找到java代码的 class文件 // jclass (*Find ...
- android JNI的.so库调用
在一篇博客中看到一篇文章,感觉描述的还可以: 在前面的博客中介绍的都是使用java开发Android应用,这篇博客将介绍java通过使用jni调用c语言做开发 为了更加形象的介绍jni,先观察下面的图 ...
- Android中关于JNI 的学习(三)在JNI层訪问Java端对象
前面两篇文章简介了JNI层跟Java层的一些相应关系,包含方法名,数据类型和方法名称等,相信在理论层面.可以非常好地帮助我们去了解JNI在Native本地开发中的作用,对JNI的一些概念也有了一个初步 ...
- JNI学习笔记_Java调用C —— 非Android中使用的方法
一.学习笔记 1.java源码中的JNI函数本机方法声明必须使用native修饰. 2.相对反编译 Java 的 class 字节码文件来说,反汇编.so动态库来分析程序的逻辑要复杂得多,为了应用的安 ...
- (转)java 层调用Jni(Ndk) 持久化c c++ 对象
对于Jni(Ndk) 很多人应该都有印象,Android的ndk接触到的机会相对会比较多,本例子以android平台为例,pc端的话就以简单的windows为例, 编码完用vs 或是 gcc进行编译成 ...
- android开发源代码分析--多个activity调用多个jni库的方法
android开发源代码分析--多个activity调用多个jni库的方法 有时候,我们在开发android项目时会遇到须要调用多个native c/jni库文件,下面是本人以前实现过的方法,假设有知 ...
- Android NDK学习(四):C/C++层调用JAVA
一.从C/C++层调用JAVA层代码(无参数调用) //在c代码里面调用java代码里面的方法 // java 反射 // 1 . 找到java代码的 class文件 // jclass (*Find ...
随机推荐
- 回顾javase点滴
数据类型 8种基本数据类型和引用类型 数据类型 占用位数 存储方式 最小值 最大值 默认值 byte 8 1+7 -128(-2^7) 127(2^7-1) 0 short 16 1+15 -3276 ...
- keilkill.bat
一.批处理文件 批处理文件是无格式的文本文件,它包含一条或多条命令.它的文件扩展名为 .bat 或 .cmd.在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用Cmd.exe按照该文 ...
- C++默认参数值函数
1.默认参数值的函数 C++语言允许在定义函数时给其中或某些形式参数(形参)指定默认值,方法就是在相应的形参后面写上“=默认值”,如果省略了对应位置上的实参的值,则在执行被调函数时以该形参的默认值进行 ...
- list和数组之间相互的转化
list变成数组: String[] str=(String[]) list.toArray(new String[list.size()]); 数组变成list: List<String> ...
- django HTTP请求(Request)和回应(Response)对象
Django使用request和response对象在系统间传递状态.—(阿伦)当一个页面被请示时,Django创建一个包含请求元数据的 HttpRequest 对象. 然后Django调入合适的视图 ...
- 关于 OneAPM Cloud Test DNS 监控的几个重要问题
你注意到了吗?OneAPM Cloud Test 已经全面开启支持 DNS 监控了! CT 产品自上线以来一直致力于产品完善,希望能够尽可能全面地满足用户需求,为您提供完美的用户体验.目前 Cloud ...
- CISCO的HTTP/HTTPS/SSH配置测试完成
按实验一步一步,倒是很容易的,也理解罗~~ START-CONFIG粗配置文件如下: r1#show run Building configuration... Current configurati ...
- 李洪强漫谈iOS开发[C语言-027]-自增与自减运算符
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: SELECT command denied to user’
Linux环境 Mysql+Hibernate command denied to user 错误 错误信息 如下: com.mysql.jdbc.exceptions.jdbc4.MySQLSynt ...
- git rebase实战
在develop分支上rebase另外一个分支master,是将master作为本地,develop作为远端来处理的. 最后的效果是,develop分支看起来像是在master分支的最新的节点之后才进 ...