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

顺德网站制作案例咨询如何注册免费网站

顺德网站制作案例咨询,如何注册免费网站,权威的公司网站制作,办公室装修风格目录 一、JNI简介1.1 什么是JNI1.2 用途1.3 优点 二、初探JNI2.1 新建cpp\cmake2.2 build.gradle配置2.3 java层配置2.4 cmake和c 三、API详解3.1 JNI API3.1.1 数据类型3.1.2 方法 3.2 CMake脚本 四、再探JNI 一、JNI简介 1.1 什么是JNI JNI#xff08;Java Native Interfa… 目录 一、JNI简介1.1 什么是JNI1.2 用途1.3 优点 二、初探JNI2.1 新建cpp\cmake2.2 build.gradle配置2.3 java层配置2.4 cmake和c 三、API详解3.1 JNI API3.1.1 数据类型3.1.2 方法 3.2 CMake脚本 四、再探JNI 一、JNI简介 1.1 什么是JNI JNIJava Native Interface是Java提供的一种机制用于实现Java和本地Native代码之间的交互。通过JNIJava程序可以调用本地代码如C、C中的函数实现跨语言的互操作性。 1.2 用途 JNI主要用于以下几个方面 调用系统级别的库和函数可以使用JNI调用操作系统提供的底层功能如文件操作、网络通信等。 提高性能通过JNI将性能关键的部分用本地代码实现可以提高程序的执行效率。 访问硬件资源JNI可以用于访问硬件资源如摄像头、传感器等。 调用第三方库可以使用JNI调用第三方的本地库以实现更多功能。 1.3 优点 使用JNI具有以下几个优点 跨语言支持可以与本地代码如C、C进行无缝交互扩展了Java的能力。 性能优势通过JNI可以将性能关键的部分用本地代码实现提高程序的执行效率。 访问系统资源可以通过JNI访问系统级别的资源和功能扩展了Java程序的能力。 调用第三方库可以利用JNI调用第三方的本地库扩展了Java程序的功能。 native层的代码往往更加安全反编译so文件比反编译jar文件要难得多往往把涉及到密码密钥相关的功能用C/C实现然后java层通过jni调用 通过JNIJava程序可以充分利用本地代码的优势实现更多功能和性能优化同时也扩展了Java的应用领域。 二、初探JNI 为了更直接了解JNI用一个简单的示例先来看一下JNI。 2.1 新建cpp\cmake 使用安卓Studio 在app/src/main文件夹下新建cpp文件夹 cpp文件夹下新建CMakeLists.txt和native-lib.cpp 2.2 build.gradle配置 配置模块名称myjni和产出的架构平台 defaultConfig {applicationId com.henry.basicnamespace com.henry.basic......ndk {// 指定库名称moduleName myjni// 指定需要产出哪些架构平台abiFilters arm64-v8a, armeabi-v7a, x86, x86_64}}指定CMake脚本路径和版本号 android {compileSdk 34......externalNativeBuild {cmake {path file(src/main/cpp/CMakeLists.txt)version 3.22.1}} }2.3 java层配置 定义一个JNIDemo 类 静态加载myjni 库 native方法返回String字符串一会在c层面实现。 public class JNIDemo {static {System.loadLibrary(myjni);}public JNIDemo() {}public native String helloJni();}static { System.loadLibrary(myjni); } 会在类被加载到内存中时执行。当首次使用该类时Java虚拟机会加载并初始化这个类执行静态代码块中的代码从而加载本地库 myjni。这确保了在调用任何类方法或创建类实例之前本地库已经被加载进内存以便后续的JNI调用可以正常进行。 Launcher中的Activity 在Oncreate中实例化JNIDemo并调用native方法。 public class jniActivity extends AppCompatActivity {String TAG henry;Overrideprotected void onCreate(Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_dialog_test);JNIDemo demo new JNIDemo();Log.d(TAG, : demo.helloJni());}}2.4 cmake和c 上层和配置已经完成 接下来就剩下c层面的实现和cmake脚本的编写了。 初学者看到cmake脚本肯定会头大建议新建工程时选择C工程会自动生成Cmake脚本和cpp层面的实现在此基础上学习Cmake。 回到我们当前的工程编写c和Cmake native-lib.cpp #include jni.h #include stringextern C JNIEXPORT jstring JNICALL Java_com_henry_cmaketest_JNIDemo_helloJni(JNIEnv *env, jobject thiz) {// TODO: implement helloJni()std::string hello Hello from C;return env-NewStringUTF(hello.c_str()); }1.#include jni.h包含了JNI的头文件提供了JNI的相关函数和数据结构的定义。 2.#include string包含了C标准库中的字符串处理相关的头文件。 3.extern “C”指定了使用C语言的调用约定确保编译器正确处理函数名。 4.JNIEXPORT jstring JNICALL定义了本地方法的返回类型为 jstring表示返回一个Java的字符串对象。JNIEXPORT 和 JNICALL 是JNI的宏定义用于声明本地方法。 5.Java_com_henry_cmaketest_JNIDemo_helloJni(JNIEnv *env, jobject thiz)实现了一个名为 helloJni 的本地方法该方法与Java中的 JNIDemo 类中的 helloJni 方法对应。JNIEnv *env 是JNI环境指针jobject thiz 是Java对象。 std::string hello “Hello from C”;创建一个C字符串 hello内容为 “Hello from C”。 return env-NewStringUTF(hello.c_str());使用JNI环境指针 env 的 NewStringUTF 方法将C字符串转换为Java字符串对象并返回给Java调用方。 CMakeLists.txt cmake_minimum_required(VERSION 3.22.1)project(myjni)add_library(${CMAKE_PROJECT_NAME} SHARED# List C/C source files with relative paths to this CMakeLists.txt.native-lib.cpp)target_link_libraries(${CMAKE_PROJECT_NAME}# List libraries link to the target libraryandroidlog)1.指定了CMake的最低版本要求为3.22.1 2.定义了项目名称为 “myjni”。 3.添加一个名为 ${CMAKE_PROJECT_NAME} 的共享库这里会被替换为 “myjni”。共享库类型为 SHARED表示构建一个共享库。native-lib.cpp 是该共享库的源文件用于实现JNI的本地方法。 4.将目标库 ${CMAKE_PROJECT_NAME} 与指定的库进行链接。在这里目标库会链接到 android 库和 log 库。android 库提供了Android平台相关的功能和API而 log 库用于在Android平台上输出日志。 运行看一下LOG输出 正是我们native-lib.cpp里面定义的字符串。 本地使用Everything搜一下myjni字段 打开.bat: 相关命令带一些参数 打开txt: 先编译cpp文件 然后链接共享库生成libmyjni.so 打开相关.so所在文件夹四个架构的so库都已生成。 三、API详解 初探JNI已经完毕接下来需要归纳一些知识了稍微大一点的项目用到的不仅仅是上面的皮毛比如CMake脚本的各种命令所代表的含义?native-lib.cpp里的JNIEXPORT、jstring 、JNICALL都是什么意思 3.1 JNI API 上例只是简单的返回了一个字符串实际上我们还可以做很多事情jni.h都给我们定义好了标准我们按照它的标准来即可。 比如java中叫booleanjni中叫jbooleanjni给我们提供了若干个映射表将java中的类型与jni中的类型进行了一 一映射其中包括基本数据类型映射引用数据类型映射方法签名(包含参数和返回值)映射以下是这三个映射表 3.1.1 数据类型 基本数据类型映射表 引用数据类型映射表 方法签名 示例 public native String stringJni();public native float floatJni(int number,Boolean enabled);对应的native层 extern C JNIEXPORT jfloat JNICALL Java_com_henry_cmaketest_JNIDemo_floatJni(JNIEnv *env, jobject thiz, jint number, jobject enabled) { } extern C JNIEXPORT jstring JNICALL Java_com_henry_cmaketest_JNIDemo_stringJni(JNIEnv *env, jobject thiz) { }顺便讲一下J开头所代表的含义 符号描述extern “C”用于指定函数按照 C 的方式进行编译。在 JNI 开发中由于 JNI 是用 C 语言编写的因此需要使用 extern “C” 来告诉编译器按照 C 的方式进行编译以确保函数名不会被 C 的名称修饰name mangling。JNIEXPORT这是一个宏定义用于指示编译器将函数导出为共享库中的一个 JNI 函数。在 JNI 开发中通常会使用这个宏定义来声明 JNI 函数。JNICALL这是一个宏定义用于指示 JNI 函数的调用约定。在 JNI 开发中通常会使用这个宏定义来声明 JNI 函数的调用约定。JNIEnv *env这是一个指向 JNI 环境的指针用于在本地代码中与 Java 虚拟机进行交互。通过 env 可以调用 JNI 提供的函数来获取 Java 对象、调用 Java 方法等操作。jobject thiz这是一个代表当前对象的引用通常用于在本地代码中调用 Java 对象的方法。在 JNI 中thiz 代表当前调用 JNI 函数的 Java 对象。 3.1.2 方法 jni访问调用对象 方法描述GetObjectClass获取调用对象的类我们称其为targetFindClass根据类名获取某个类我们称其为targetIsInstanceOf判断一个类是否为某个类型IsSamObject是否指向同一个对象 jni访问java成员变量的值 方法描述GetFieldId根据变量名获取target中成员变量的IDGetIntField根据变量ID获取int变量的值对应的还有bytebooleanlong等SetIntField修改int变量的值对应的还有bytebooleanlong等 jni访问java静态变量的值 方法描述GetStaticFieldId根据变量名获取target中静态变量的IDGetStaticIntField根据变量ID获取int静态变量的值对应的还有bytebooleanlong等SetStaticIntField修改int静态变量的值对应的还有bytebooleanlong等 jni访问java成员方法 方法描述GetMethodID根据方法名获取target中成员方法的IDCallVoidMethod执行无返回值成员方法CallIntMethod执行int返回值成员方法对应的还有bytebooleanlong等 jni访问java静态方法 方法描述GetStaticMethodID根据方法名获取target中静态方法的IDCallStaticVoidMethod执行无返回值静态方法CallStaticIntMethod执行int返回值静态方法对应的还有bytebooleanlong等 jni访问java构造方法 方法描述GetMethodID根据方法名获取target中构造方法的ID注意方法名传NewObject创建对象 jni创建引用 方法描述NewGlobalRef创建全局引用NewWeakGlobalRef创建弱全局引用NewLocalRef创建局部引用DeleteGlobalRef释放全局对象引用不主动释放会导致内存泄漏DeleteLocalRef释放局部对象引用不主动释放会导致内存泄漏 除此之外jni还提供了异常处理机制处理方式跟java一样有两种要么往上(java层)抛要么自己捕获处理 方法描述ExceptionOccurred判断是否有异常发生ExceptionClear清除异常Throw往上(java层)抛出异常ThrowNew往上(java层)抛出自定义异常 以上只是常用API,其他的可以自行到jni.h文件里去查看。 3.2 CMake脚本 CMake编写规则: CMakeLists会自动创建两个变量PROJECT_SOURCE_DIR和PROJECT_NAME 字段描述示例cmake_minimum_required指定所需的最低 CMake 版本。cmake_minimum_required(VERSION 3.10)project定义项目的名称project(MyProject)PROJECT_SOURCE_DIR本CMakeLists.txt所在的文件夹路径PROJECT_NAME本CMakeLists.txt的project名称add_library(${CMAKE_PROJECT_NAME} SHARED native-lib.cpp)add_executable添加可执行文件指定可执行文件的名称和源文件。add_executable(my_executable main.cpp)add_library添加库文件指定库文件的名称和源文件。add_library(my_library my_source.cpp)target_link_libraries链接库文件到可执行文件或其他库文件。target_link_libraries(my_executable my_library)include_directories添加头文件搜索路径。include_directories(include)link_directories添加库文件搜索路径。link_directories(lib)set设置变量。set(SRC_FILES main.cpp)if条件判断。if(CONDITION)…endif()foreach遍历列表。foreach(item IN LISTS LIST_VARIABLE) …endforeach()message输出消息。message(“Hello, CMake!”)install安装目标文件到指定目录。install(TARGETS my_executable DESTINATION bin)find_package查找外部库。find_package(OpenGL REQUIRED)add_definitions添加编译器选项。add_definitions(-DDEBUG)add_subdirectory添加子目录。add_subdirectory(subdir)find_library在 CMake 中用于查找指定的库文件。find_library(VAR name)VAR指定一个变量用于存储查找到的库文件的路径。name要查找的库文件的名称。set_target_properties用于设置目标的属性。set_target_properties(my_executable PROPERTIES CXX_STANDARD 11)IMPORTED_LOCATION指定 IMPORTED 目标的位置。set_target_properties(my_library PROPERTIES IMPORTED_LOCATION /path/to/libmylib.so)log-lib是一个变量通常用于存储 Android NDK 中日志库的名称target_link_libraries(my_executable ${log-lib})。loglog 是 Android NDK 中的一个系统库用于输出日志信息。target_link_libraries(my_executable log) 来链接 log 库。PROPERTIESPROPERTIES 是用于设置目标属性的关键字 通过 set_target_properties 函数可以设置目标的各种属性如编译选项、输出路径等。set_target_properties(my_executable PROPERTIES CXX_STANDARD 11) 设置可执行文件的 C 标准为 C11 四、再探JNI 这一次多用一些JNI相关知识写一个demo 新建一个test方法并添加到native-lib.cpp中。 再新建一个mycpp.cpp文件activity中新建一个test2()方法jni实现在mycpp.cpp文件中 CMakeLists.txt中添加mycpp.cpp cmake_minimum_required(VERSION 3.22.1)project(myjni)add_library(${CMAKE_PROJECT_NAME} SHARED# List C/C source files with relative paths to this CMakeLists.txt.native-lib.cpp mycpp.cpp)target_link_libraries(${CMAKE_PROJECT_NAME}# List libraries link to the target libraryandroidlog)Activity: public class jniActivity extends AppCompatActivity {static {System.loadLibrary(myjni);}private int num 1;String TAG henry;private TextView tv;Overrideprotected void onCreate(Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.jnitest);JNIDemo demo new JNIDemo();tv findViewById(R.id.jniview);Log.d(TAG, : demo.stringJni());tv.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View v) {test();test2();}});}public native void test();public native void test2(); }mycpp.cpp: #include jni.h #include string #include android/log.h #define TAG henry #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) // 定义LOGD类型extern C JNIEXPORT void JNICALL Java_com_henry_cmaketest_jniActivity_test2(JNIEnv *env, jobject thiz) {LOGD(-------------new cpp test); }native-lib.cpp: #include jni.h #include string #include android/log.h#define TAG henry #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) // 定义LOGD类型extern C JNIEXPORT jstring JNICALL Java_com_henry_cmaketest_JNIDemo_stringJni(JNIEnv *env, jobject thiz) {std::string hello Hello from C;return env-NewStringUTF(hello.c_str()); }/*** 参数一JNIEnv* env表示指向可用JNI函数表的接口指针所有跟jni相关的操作都需要通过env来完成* 参数二jobject是调用该方法的java对象这里是MainActivity调用的所以thiz代表MainActivity* 方法名Java_包名_类名_方法名*/ extern C JNIEXPORT void JNICALL Java_com_henry_cmaketest_jniActivity_test(JNIEnv *env, jobject thiz) {//获取Activity的class对象jclass clazz env-GetObjectClass(thiz);//获取MainActivity中num变量id/**参数1MainActivity的class对象参数2变量名称参数3变量类型具体见上《表3-方法签名》**/jfieldID numFieldId env-GetFieldID(clazz, num, I);//根据变量id获取num的值jint oldValue env-GetIntField(thiz, numFieldId);//将num变量的值1env-SetIntField(thiz, numFieldId, oldValue 1);//重新获取num的值jint num env-GetIntField(thiz, numFieldId);//先获取tv变量idjfieldID tvFieldId env-GetFieldID(clazz, tv, Landroid/widget/TextView;);//根据变量id获取textview对象jobject tvObject env-GetObjectField(thiz, tvFieldId);//获取textview的class对象jclass tvClass env-GetObjectClass(tvObject);//获取setText方法ID/**参数1textview的class对象参数2方法名称参数3方法参数类型和返回值类型具体见上《表3-方法签名》**/jmethodID methodId env-GetMethodID(tvClass, setText, ([CII)V);//获取setText所需的参数//先将num转化为jstringchar buf[64];sprintf(buf, %d, num);jstring pJstring env-NewStringUTF(buf);const char *value env-GetStringUTFChars(pJstring, JNI_FALSE);//创建char数组长度为字符串num的长度jcharArray charArray env-NewCharArray(strlen(value));//开辟jchar内存空间jchar *pArray (jchar *) calloc(strlen(value), sizeof(jchar));//将num字符串缓冲到内存空间中for (int i 0; i strlen(value); i) {*(pArray i) *(value i);}//将缓冲的值写入到上面创建的char数组中env-SetCharArrayRegion(charArray, 0, strlen(value), pArray);//调用setText方法env-CallVoidMethod(tvObject, methodId, charArray, 0, env-GetArrayLength(charArray));//释放资源env-ReleaseCharArrayElements(charArray, env-GetCharArrayElements(charArray, JNI_FALSE), 0);free(pArray);pArray NULL; }看一下效果 参考链接 CMakeLists.txt的超傻瓜手把手教程 JNI 从入门到实践爆肝万字详解 基础JNI语法和常见使用
http://www.dnsts.com.cn/news/104639.html

相关文章:

  • 做教案找资料有哪些网站汽车配件加工网
  • 网站建设与管理题目常州规划网站
  • 福建省闽侯县建设局网站佛山网站搜索优化
  • 母婴网站开发昆山网站建设书生商友
  • 网站不足之处西安网站seo
  • 学网站建设好么网站建设免费软件有哪些
  • 做有色研究的网站网站建设功能是什么意思
  • wordpress 获取文章分类id北京网站制作网站优化
  • 在百度备案网站郑州妇科医院哪个医院最好
  • 长春 网站建设网络推广网页设计wordpress模板更改
  • 大学学校网站建设方案海门建设厅网站
  • 上传宝贝网站建设属于什么类目网站建设网站排名
  • 建站系统多少钱wordpress 内容模板
  • 广东专业网站开发企业网站排名运营
  • 搭建企业网站优秀网页版式设计
  • 潍坊网站建设优化排名网站分类代码
  • 企业网站建设内容报价做外贸学网站
  • 百度引擎入口windows优化大师功能
  • 网站开发工作进展情况中山今科网站建设
  • 河南免费网站建设公司推荐网站建设深圳哪家好
  • 网站建设参考书百度调整导致网站排名下降
  • 怎样建设数字中国新泰网站seo
  • 做网站广告的点wordpress简体中文
  • 网站未授权cas要怎么做小程序二次开发多少钱
  • 知行网站建设扁平风格网站模板
  • 接私活做预算的网站百度商桥代码怎么添加到网站
  • 长春建站方案东莞网站的优化
  • 男和男人怎么做那个视频网站济南建设工程交易网
  • 1m宽带做网站番禺做网站
  • 内江建设局网站Pk10网站建设多少钱