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

网站建设行wordpress模板好用吗

网站建设行,wordpress模板好用吗,唐山专业网站建设,好听有创意的广告公司名字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.hkea.cn/news/14314959/

相关文章:

  • 网页设计网站官网WordPress登录页提示
  • 安徽省通信建设管理局网站浪尖工业设计公司官网
  • 全国建设部网站简述电子商务网站开发的主要步骤
  • 微商城网站建设公司的价格网红营销推广
  • 如何做一个更新网站网站建设计入哪个明细科目
  • 网站一直没有收录北京网站关键词排名推广
  • mcms怎么做网站专业柳州网站建设推荐
  • 网站开发设备费用计入什么科目电商 网站 设计
  • ui怎样做网站自动发卡网站怎么做
  • 贵阳市观山湖区网站建设可以自己制作图片的软件
  • 外贸累网站仿贴吧的网站
  • 怎样做约票的网站意思网站建设维护宣传
  • 网站如何不被收录线上店免费推广的软件
  • 网站建设面试表微信长图的免费模板网站
  • 乔括云智能建站软件开发项目管理书籍
  • 嘉兴网站建设托管物流网站建设公司
  • 企业网站建设的收获成都网站制作scgckj
  • 怎样只做自己的网站自己电脑做电影网站
  • 榆林网站制作公司网站的备案号是如何链接的
  • 北京网站设计公司兴田德润简介wordpress文章首页不显示怎么办
  • 人人商城网站开发成都网站建站推广
  • 深圳三站合一网站建设互联网推广属于什么经营范围
  • 百度手机网站制作信息流广告投放
  • 做企业网站市场分析vs2015做网站
  • 在哪注册网站东风地区网站建设价格
  • 河南省建设监理网站重庆最新网站备案
  • 国际物流网站建设男人互做网站
  • 阿里巴巴网站图片怎么做的优秀的品牌策划案例
  • 做的新网站做百度推广怎么弄做网站要有哪些知识
  • 廊坊网站关键词推广wordpress的文件权限设置