当前位置: 首页 > news >正文

网站建设行python语言变量命名规则

网站建设行,python语言变量命名规则,热搜在哪里可以看,站长工具的使用seo综合查询排名1.1 JNI(Java Native Interface) 提供一种Java字节码调用C/C的解决方案#xff0c;JNI描述的是一种技术。 1.2 NDK(Native Development Kit) Android NDK 是一组允许您将 C 或 C#xff08;“原生代码”#xff09;嵌入到 Android 应用中的工具#xff0c;NDK描述的是工具集…1.1 JNI(Java Native Interface) 提供一种Java字节码调用C/C的解决方案JNI描述的是一种技术。 1.2 NDK(Native Development Kit) Android NDK 是一组允许您将 C 或 C“原生代码”嵌入到 Android 应用中的工具NDK描述的是工具集。 能够在 Android 应用中使用原生代码对于想执行以下一项或多项操作的开发者特别有用 在平台之间移植其应用。重复使用现有库或者提供其自己的库供重复使用。在某些情况下提高性能特别是像游戏这种计算密集型应用。 1.3 JNI方法注册 1.3.1静态注册 当Java层调用navtie函数时会在JNI库中根据函数名查找对应的JNI函数。如果没找到会报错。如果找到了则会在native函数与JNI函数之间建立关联关系其实就是保存JNI函数的函数指针。下次再调用native函数就可以直接使用这个函数指针。 JNI函数名格式需将”.”改为”_” Java_ 包名com.example.auto.jnitest 类名(MainActivity) 函数名(stringFromJNI) 静态方法的缺点 要求JNI函数的名字必须遵循JNI规范的命名格式名字冗长容易出错初次调用会根据函数名去搜索JNI中对应的函数会影响执行效率需要编译所有声明了native函数的Java类每个所生成的class文件都要用javah工具生成一个头文件 1.3.2动态注册 通过提供一个函数映射表注册给JVM虚拟机这样JVM就可以用函数映射表来调用相应的函数就不必通过函数名来查找需要调用的函数。 Java与JNI通过JNINativeMethod的结构来建立函数映射表它在jni.h头文件中定义其结构内容如下 typedef struct {const char* name;const char* signature;void* fnPtr; } JNINativeMethod;创建映射表后调用RegisterNatives函数将映射表注册给JVM;当Java层通过System.loadLibrary加载JNI库时会在库中查JNI_OnLoad函数。可将JNI_OnLoad视为JNI库的入口函数需要在这里完成所有函数映射和动态注册工作及其他一些初始化工作。 1.4 数据类型转换 1.4.1 基础数据类型转换 1.4.2 引用数据类型转换 除了Class、String、Throwable和基本数据类型的数组外其余所有Java对象的数据类型在JNI中都用jobject表示。Java中的String也是引用类型但是由于使用频率较高所以在JNI中单独创建了一个jstring类型。 引用类型不能直接在 Native 层使用需要根据 JNI 函数进行类型的转化后才能使用;多维数组含二维数组都是引用类型需要使用 jobjectArray 类型存取其值 例如二维整型数组就是指向一位数组的数组其声明使用方式如下 //获得一维数组的类引用即jintArray类型 jclass intArrayClass env-FindClass([I); //构造一个指向jintArray类一维数组的对象数组该对象数组初始大小为length类型为 jsizejobjectArray obejctIntArray env-NewObjectArray(length ,intArrayClass , NULL);1.4.3 JNI函数签名信息 由于Java支持函数重载因此仅仅根据函数名是没法找到对应的JNI函数。为了解决这个问题JNI将参数类型和返回值类型作为函数的签名信息。 JNI规范定义的函数签名信息格式 (参数1类型字符…)返回值类型字符 函数签名例子: JNI常用的数据类型及对应字符: 1.4.4 JNIEnv介绍 JNIEnv概念 : JNIEnv是一个线程相关的结构体, 该结构体代表了 Java 在本线程的运行环境。通过JNIEnv可以调用到一系列JNI系统函数。JNIEnv线程相关性 每个线程中都有一个 JNIEnv 指针。JNIEnv只在其所在线程有效, 它不能在线程之间进行传递。 注意在C创建的子线程中获取JNIEnv要通过调用JavaVM的AttachCurrentThread函数获得。在子线程退出时要调用JavaVM的DetachCurrentThread函数来释放对应的资源否则会出错。 JNIEnv 作用 访问Java成员变量和成员方法调用Java构造方法创建Java对象等。 1.5 JNI编译 1.5.1 ndkBuild 使用ndk-build编译生成so文件 1.5.2 Cmake编译 CMake 则是一个跨平台的编译工具它并不会直接编译出对象而是根据自定义的语言规则CMakeLists.txt生成 对应 makefile 或 project 文件然后再调用底层的编译 在Android Studio 2.2 之后支持Cmake编译。 add_library 指令 语法add_library(libname [SHARED | STATIC | MODULE] [EXCLUDE_FROM_ALL] [source]) 将一组源文件 source 编译出一个库文件并保存为 libname.so (lib 前缀是生成文件时 CMake自动添加上去的)。其中有三种库文件类型不写的话默认为 STATIC; SHARED: 表示动态库可以在(Java)代码中使用 System.loadLibrary(name) 动态调用STATIC: 表示静态库集成到代码中会在编译时调用MODULE: 只有在使用 dyId 的系统有效如果不支持 dyId则被当作 SHARED 对待EXCLUDE_FROM_ALL: 表示这个库不被默认构建除非其他组件依赖或手工构建; #将compress.c 编译成 libcompress.so 的共享库 add_library(compress SHARED compress.c)target_link_libraries 指令 语法target_link_libraries(target library debug | optimized library2…) 这个指令可以用来为 target 添加需要的链接的共享库同样也可以用于为自己编写的共享库添加共享库链接。如 #指定 compress 工程需要用到 libjpeg 库和 log 库 target_link_libraries(compress libjpeg ${log-lib})find_library 指令 语法find_library( name1 path1 path2 …) VAR 变量表示找到的库全路径包含库文件名 。例如 find_library(libX X11 /usr/lib) find_library(log-lib log) #路径为空应该是查找系统环境变量路径Android NDK 开发CMake 使用 1.5.3 Abi架构 ABIApplication binary interface应用程序二进制接口。不同的CPU 与指令集的每种组合都有定义的 ABI (应用程序二进制接口)一段程序只有遵循这个接口规范才能在该 CPU 上运行所以同样的程序代码为了兼容多个不同的CPU需要为不同的 ABI 构建不同的库文件。当然对于CPU来说不同的架构并不意味着一定互不兼容。 armeabi设备只兼容armeabiarmeabi-v7a设备兼容armeabi-v7a、armeabiarm64-v8a设备兼容arm64-v8a、armeabi-v7a、armeabiX86设备兼容X86、armeabiX86_64设备兼容X86_64、X86、armeabimips64设备兼容mips64、mipsmips只兼容mips 根据以上的兼容总结我们还可以得到一些规律 armeabi的SO文件基本上可以说是万金油它能运行在除了mips和mips64的设备上但在非armeabi设备上运行性能还是有所损耗64位的CPU架构总能向下兼容其对应的32位指令集如x86_64兼容X86arm64-v8a兼容armeabi-v7amips64兼容mips 1.5.4 Jni技术实现原理 我们知道cpu只认得 “0101101” 类似这种符号 C、C 这些代码最终都得通过编译、汇编成二进制代码cpu才能识别。而Java比C、C又多了一层虚拟机过程也复杂许多。Java代码经过编译成class文件、虚拟机装载等步骤最终在虚拟机中执行。class文件里面就是一个结构复杂的表而最终告诉虚拟机怎么执行的就靠里面的字节码说明。 Java虚拟机在执行的时候可以采用解释执行和编译执行的方式执行但最终都是转化为机器码执行。 Java虚拟机运行时的数据区包括方法区、虚拟机栈、堆、程序计数器、本地方法栈。 问题来了按我目前的理解如果是解释执行那么方法区中应该存的是字节码那执行的时候通过JNI 动态装载的c、c库放哪去怎么执行这个问题搜索了许多标题写着”JNI实现原理”的文章都是抄来抄去并没去探究如何实现的只是讲了java如何使用JNI。好吧就从如何使用JNI开始。 1.6 JNI的简单实现 参考文章《Java JNI简单实现》、《JAVA基础之理解JNI原理》 假设当前的目录结构如下 - | - maniu| Test.java 1.首先编写java文件 Test.java package maniu; public class Test{static{System.loadLibrary(bridge);}public native int nativeAdd(int x,int y);public static void main(String[] args){Test obj new Test();System.out.printf(%d\n,obj.nativeAdd(2012,3));} } 代码很简单这里声明了nativeAdd(int x,inty)的方法执行的时候简单的打出执行的结果。另外这里调用API加载名称叫bridge的库接下来就来实现这个库。 2.生成JNI调用需要的头文件 javac maniu/Test.java javah -jni maniu.Test 现在目录结构是这样的 - | - maniu| Test.java| Test.class | - maniu_Test.h maniu_Test.h头文件内容如下 /* DO NOT EDIT THIS FILE - it is machine generated */ #include jni.h /* Header for class maniu_Test */#ifndef _Included_maniu_Test #define _Included_maniu_Test #ifdef __cplusplus extern C { #endif /** Class: maniu_Test* Method: nativeAdd* Signature: (II)I*/ JNIEXPORT jint JNICALL Java_maniu_Test_nativeAdd(JNIEnv *, jobject, jint, jint);#ifdef __cplusplus } #endif 1.6.1 生成的代码阅读 经常会见到__cplusplus关键字比如下面的代码 #ifdef __cplusplus extern C { #endif JNIEXPORT jint JNICALL Java_maniu_Test_nativeAdd(JNIEnv *, jobject, jint, jint); #ifdef __cplusplus } #endif这里面两种关键字都是为了实现C与C兼容的extern “C”是用来在C程序中声明或定义一个C的符号比如 extern “C” {int func(int);int var;}上面的代码C编译器会将在extern “C”的大括号内部的代码当做C语言来处理。 由于C和C毕竟是不同的为了实现某个程序在C和C中都是兼容的如果定义两套头文件未免太过麻烦所以就有了__cplusplus的出现这个是在C中特有的__cplusplus其实就是C也就有了上面第一段代码的使用如果这段代码是在C文件中出现那么经过编译后该段代码就变成了 /**********C文件中条件编译后结果***************/ extern C { JNIEXPORT jint JNICALL Java_maniu_Test_nativeAdd(JNIEnv *, jobject, jint, jint); }而在C文件中经过条件编译该段代码变成了 /**********C文件中条件编译后结果*************/ JNIEXPORT jint JNICALL Java_maniu_Test_nativeAdd(JNIEnv *, jobject, jint, jint);3.native方法的实现 这里新增bridge.c文件来实现之前声明的native方法目录结构如下 - | - maniu| Test.java| Test.class | - maniu_Test.h | - bridge.c bridge.c的内容如下 #include maniu_Test.hJNIEXPORT jint JNICALL Java_maniu_Test_nativeAdd (JNIEnv * env, jobject obj, jint x, jint y){return xy; } 这里的实现只是简单的把两个参数相加然后返回。 4.生成动态链接库 gcc -shared -o dll_demo.dll bridge.c 最后需要注意一点的是 -o 选项我们在java代码中调用的是System.loadLibrary(xxx),那么生成的动态链接库的名称就必须是libxxx.so的形式这里指Linux环境否则在执行java代码的时候就会报 java.lang.UnsatisfiedLinkError: no XXX in java.library.path 的错误也就是说找不到这个库我在这里被坑了一小段时间。 好了现在的目录结构如下 - | - maniu| Test.java| Test.class | - maniu_Test.h | - bridge.c | - libbridge.so 5.执行代码验证结果 java -Djava.library.path. maniu.Test 2015 okJava 使用JNI的最简单的例子就完成了。 1.6.2 JNI实现原理 那么我们的问题还没解决刚刚生成的动态链接库”libbridge.so”是怎么装进内存的native方法怎么调用跟普通的方法调用有什么区别吗 我们把Test.java改改增加普通的方法”int add(int x,int y)” Test.java package maniu; public class Test{static{System.loadLibrary(bridge);}public native int nativeAdd(int x,int y);public int add(int x,int y){return xy;}public static void main(String[] args){Test obj new Test();System.out.printf(%d\n,obj.nativeAdd(2012,3));System.out.printf(%d\n,obj.add(2012,3));} } 我们把它编译成class文件再看看class文件中native方法和普通方法有何区别 javac maniu/Test.java javap -verbose maniu.Test 解析后”nativeAdd”和”add”两个方法的结果如下 public native int nativeAdd(int, int);flags: ACC_PUBLIC, ACC_NATIVEpublic int add(int, int);flags: ACC_PUBLICCode:stack2, locals3, args_size30: iload_1 1: iload_2 2: iadd 3: ireturn LineNumberTable:line 8: 0 可见普通的“add”方法是直接把字节码放到code属性表中而native方法与普通的方法通过一个标志“ACC_NATIVE”区分开来。java在执行普通的方法调用的时候可以通过找方法表再找到相应的code属性表最终解释执行代码那么对于native方法在class文件中并没有体现native代码在哪里只有一个“ACC_NATIVE”的标识那么在执行的时候改怎么找到动态链接库的代码呢 只能从System.loadLibrary()入手了
http://www.w-s-a.com/news/4278/

相关文章:

  • 苏州和城乡建设局网站撸撸撸做最好的导航网站
  • 网站被同行抄袭怎么办深圳中装建设集团
  • 建站及推广瓦房店 网站建设
  • 怎么查网站是在哪里备案的广州电力建设有限公司网站
  • 做网站自己申请域名还是对方wordpress管理地址
  • 专门做二手书网站或appwordpress首页显示特定分类文章
  • 无锡网站设计厂家一建十个专业含金量排名
  • 网站刷链接怎么做成都高度网站技术建设公司
  • flash网站模板怎么用xml网站地图生成
  • 英文网站优化群晖wordpress中文
  • saas建站平台源码济南品牌网站建设公司
  • 网站建设一般是用哪个软件网站百度
  • 企业建站的作用是什么南宁公司网站开发
  • 厦门网站建设及维护门户网站开发视频教学
  • 可以做兼职的网站有哪些自动点击器永久免费版
  • 建购物网站怎么建呀网站怎么做中英文交互
  • 网站建设费用计入无形资产做网站用的主机
  • 佛山企业网站建设平台沈阳网站建设培训班
  • 河南企业网站优化外包网站怎么做来流量
  • 网站建设的参考文献网站设计网页的优缺点
  • WordPress多站點支付插件内江市网站建设培训
  • 做做网站已更新动漫制作专业需要学什么
  • dfv印花图案设计网站网站建设应该应聘什么岗位
  • 网站后台管理系统模板下载专业网站推广的公司哪家好
  • 克拉玛依市建设局网站网页设计板式重构
  • 网站新闻专题怎么做湖南营销型网站建设 要上磐石网络
  • 阿里云发布网站成都轨迹公布
  • php网站源码架构谷歌站群系统
  • 潮州网站seowordpress 调用置顶文章
  • 做带会员后台的网站用什么软件旅游网站建设资金请示