本地方法(JNI)——使用调用API

【0】README

1) 本文文字描述+source code 均转自 core java volume 2 , 旨在理解 本地方法(JNI)——使用调用API 的基础知识 ;
2) for source code, please visit : https://github.com/pacosonTang/core-java-volume/tree/master/coreJavaAdvanced/chapter12/chapter12_9


【1】本地方法(JNI)——使用调用API

(干货——能够把java 虚拟机嵌入到C 或 C++ 程序中)
1)problem+solution:

  • 1.1)problem:你有一个C 或 C++程序, 并且想要调用一些java 代码;
  • 1.2)solution:调用API(Invocation API) 使你能够把 java 虚拟机嵌入到 C 或者 C++ 程序中。

2)下面是你 初始化虚拟机的代码: (干货——初始化虚拟机的代码, 有点新鲜)

JavaVMOption options[1];
JavaVMInnitArgs vm_args;
JavaVM *jvm; //干货——虚拟机指针jvm
JNIEnv *env;options[0].optionString = "-Djava.class.path=.";memset(&vm_args, 0, sizeof(vm_args));
vm_args_version=JNI_VERSION_1_2;
vm_args.nOptions = 1;
vm_args.optoins = options;JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args); //初始化虚拟机

对以上代码的分析(Analysis):

  • A1) 对 JNI_CreateJavaVM 的调用将创建虚拟机, 并且使指针jvm 指向虚拟机, 使指针env 指向执行环境; (干货——创建java虚拟机)
  • A2) 可以给虚拟机提供任意数目的选项, 这只需要增加选项数组的大小和 vm_args.nOptions 的值;
  • A3)看个荔枝: options[1].optionString = “-Djava.compiler=NONE”; // 这可以钝化即时编译器; (干货——钝化即时编译器)

    • Warning) 当你陷入麻烦导致程序崩溃, 从而不能初始化 JVM 或者不能装载你的类时, 请打开 JNI 调试模式。 设置一个选项如下: (干货——虚拟机打开 JNI 调试模式)

      options[i].optionString=”-verbose:jni”; // 你将会看到一系列说明JVM 初始化进程的消息;

3)只有在调用 Invocation API 中的其他函数时, 才需要 jvm 指针。 目前,只有四个这样的函数,最重要的一个是 终止虚拟机的函数:

(*jvm)->DestoryJavaVM(jvm);

4)看个荔枝: 下面的C程序设置了 虚拟机, 然后调用了 Welcome 类的 main 方法。 (仅供了解啦, 我也不懂他的源代码,呵呵。)

/**@version 1.20 2007-10-26@author Cay Horstmann
*/#include <jni.h>
#include <stdlib.h>#ifdef _WINDOWS#include <windows.h>
static HINSTANCE loadJVMLibrary(void);
typedef jint (JNICALL *CreateJavaVM_t)(JavaVM **, void **, JavaVMInitArgs *);#endifint main()
{  JavaVMOption options[2];JavaVMInitArgs vm_args;JavaVM *jvm;JNIEnv *env;long status;jclass class_Welcome;jclass class_String;jobjectArray args;jmethodID id_main;#ifdef _WINDOWSHINSTANCE hjvmlib;CreateJavaVM_t createJavaVM;
#endifoptions[0].optionString = "-Djava.class.path=.";memset(&vm_args, 0, sizeof(vm_args));vm_args.version = JNI_VERSION_1_2;vm_args.nOptions = 1;vm_args.options = options;#ifdef _WINDOWS   hjvmlib = loadJVMLibrary();createJavaVM = (CreateJavaVM_t) GetProcAddress(hjvmlib, "JNI_CreateJavaVM");status = (*createJavaVM)(&jvm, (void **) &env, &vm_args);
#elsestatus = JNI_CreateJavaVM(&jvm, (void **) &env, &vm_args);
#endifif (status == JNI_ERR){  fprintf(stderr, "Error creating VM\n");return 1;}class_Welcome = (*env)->FindClass(env, "Welcome");id_main = (*env)->GetStaticMethodID(env, class_Welcome, "main", "([Ljava/lang/String;)V");class_String = (*env)->FindClass(env, "java/lang/String");args = (*env)->NewObjectArray(env, 0, class_String, NULL);(*env)->CallStaticVoidMethod(env, class_Welcome, id_main, args);(*jvm)->DestroyJavaVM(jvm);return 0;
}#ifdef _WINDOWSstatic int GetStringFromRegistry(HKEY key, const char *name, char *buf, jint bufsize)
{DWORD type, size;return RegQueryValueEx(key, name, 0, &type, 0, &size) == 0&& type == REG_SZ&& size < (unsigned int) bufsize&& RegQueryValueEx(key, name, 0, 0, buf, &size) == 0;
}static void GetPublicJREHome(char *buf, jint bufsize)
{HKEY key, subkey;char version[MAX_PATH];/* Find the current version of the JRE */char *JRE_KEY = "Software\\JavaSoft\\Java Runtime Environment";if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, JRE_KEY, 0, KEY_READ, &key) != 0) {fprintf(stderr, "Error opening registry key '%s'\n", JRE_KEY);exit(1);}if (!GetStringFromRegistry(key, "CurrentVersion", version, sizeof(version))) {fprintf(stderr, "Failed reading value of registry key:\n\t%s\\CurrentVersion\n", JRE_KEY);RegCloseKey(key);exit(1);}/* Find directory where the current version is installed. */if (RegOpenKeyEx(key, version, 0, KEY_READ, &subkey) != 0) {fprintf(stderr, "Error opening registry key '%s\\%s'\n", JRE_KEY, version);RegCloseKey(key);exit(1);}if (!GetStringFromRegistry(subkey, "JavaHome", buf, bufsize)) {fprintf(stderr, "Failed reading value of registry key:\n\t%s\\%s\\JavaHome\n", JRE_KEY, version);RegCloseKey(key);RegCloseKey(subkey);exit(1);}RegCloseKey(key);RegCloseKey(subkey);
}static HINSTANCE loadJVMLibrary(void)
{HINSTANCE h1, h2;char msvcdll[MAX_PATH];char javadll[MAX_PATH];GetPublicJREHome(msvcdll, MAX_PATH);   strcpy(javadll, msvcdll);strncat(msvcdll, "\\bin\\msvcr71.dll", MAX_PATH - strlen(msvcdll));msvcdll[MAX_PATH - 1] = '\0';strncat(javadll, "\\bin\\client\\jvm.dll", MAX_PATH - strlen(javadll));javadll[MAX_PATH - 1] = '\0';h1 = LoadLibrary(msvcdll);if (h1 == NULL){fprintf(stderr, "Can't load library msvcr71.dll\n");exit(1);}h2 = LoadLibrary(javadll);if (h2 == NULL){fprintf(stderr, "Can't load library jvm.dll\n");exit(1);}return h2;
}#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331458.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Shell入门(四)之数组

一、一维数组 bash支持一维数组&#xff08;不支持多维数组&#xff09;&#xff0c;并且没有限定数组的大小。 类似与C语言&#xff0c;数组元素的下标由0开始编号。 二、定义数组 在Shell中&#xff0c;用括号来表示数组&#xff0c;数组元素用"空格"符号分割开。…

aws cloud map_销毁AWS资源:Cloud-Nuke还是AWS-Nuke?

aws cloud map因此&#xff0c;您在开发帐户上工作&#xff0c;并且Terraform陷入了一个循环&#xff0c;难道不让您轻易销毁剩余资源吗&#xff1f; 进入nuke CLI的世界&#xff01; 在撰写本文时&#xff0c;我使用的是v0.1.16版本 用Go语言编写的《 Gruntwork》不会破坏掉…

mysql error 1045 的解决方法

【0】README 1&#xff09;以下是 解决方法的steps&#xff1a; step1&#xff09;点击 skip 和 cancel 退出 mysql 配置 step2&#xff09; 重启mysql server config wizard&#xff0c; 然后 remove instance step3&#xff09; 随后卸载mysql&#xff08;通过360或 …

Shell入门(五)之参数

一、Shell 传递参数 在执行 Shell 脚本时&#xff0c;向脚本传递参数&#xff0c;脚本内获取参数的格式为&#xff1a;$n。n 代表一个数字&#xff0c;0为执行文件名&#xff0c;1 为执行脚本的第一个参数&#xff0c;2 为执行脚本的第二个参数&#xff0c;以此类推 比如&…

openj9下载_Quarkus on OpenJ9 JVM和资源消耗

openj9下载除了本机模式&#xff0c;Quarkus在JVM模式下也能很好地运行&#xff0c;这有其自身的优势。 您可以使用替代的JVM&#xff0c;例如OpenJ9&#xff0c;它可以更好地消耗资源。 在下面的视频中&#xff0c;我将展示交换JVM有多么容易。 在视频中&#xff0c;我在最新…

Shell入门(六)之算术运算

一、数学运算 &#xff08;1&#xff09;原生bash不支持简单的数学运算&#xff0c;但是可以通过其他命令来实现&#xff0c;例如 awk 和 expr&#xff0c;expr 最常用。 &#xff08;2&#xff09;expr 是一款表达式计算工具&#xff0c;使用它能完成表达式的求值操作。 ex…

java数据库编程——执行SQL 语句

【0】README 1&#xff09; 本文文字描述source code 均转自 core java volume 2 &#xff0c; 旨在理解 java数据库编程——执行SQL 语句 的基础知识 &#xff1b; 2&#xff09;for source code, please visit &#xff1a; https://github.com/pacosonTang/core-java-vol…

php cdi_Quarkus的其他(非标准)CDI功能

php cdiQuarkus支持CDI&#xff08;上下文和依赖注入&#xff09;2.0&#xff0c;但并非全部&#xff0c;仅支持最常见的功能。 但是&#xff0c;Quarkus确实包含一些非标准功能&#xff0c;这些功能对于开发人员非常方便&#xff0c;我想在下面的视频中进行展示。 不管您是否…

Shell入门(七)之关系运算

一、关系运算 shell关系运算符只支持数字&#xff0c;不支持字符串&#xff0c;除非字符串的值是数字。 a10 b20 运算符说明举例-eq检测两个数是否相等&#xff0c;相等返回 true。[ $a -eq $b ] 返回 false。-ne检测两个数是否相等&#xff0c;不相等返回 true。[ $a -ne $…

java数据库编程——Insert and Retrieve Images from MySql Table Using Java

【0】README0.1&#xff09;本文翻译自 http://harmeetsingh13.blogspot.jp/2013/03/insert-and-retrieve-images-from-mysql.html【1】正文如下&#xff1a;段1&#xff09;演示 从数据库表中插入和查询出图片。大多数情况下&#xff0c;图片数据都存储在数据库外部的一些文件…

Shell入门(八)之布尔运算

一、常规的布尔运算 常规的布尔运算符有&#xff1a;!、&&、|| 使用语法 ! exp exp && exp exp || exp [[ n op m && a op b]] ... exp为[ n op m ]或test n op m或true或false 二、条件测试的布尔运算 条件测试的布尔运算有&#xff1a;!、…

java switch语句_Java 14:查看更新的switch语句

java switch语句于2020年3月发布的JDK 14带有switch语句的更新版本。 这是JDK 12和JDK 13中的预览功能。 要了解差异&#xff0c;让我们看一个简单的示例。 假设我们要基于DayOfWeek枚举来计算每日工作时间。 使用旧的使用switch语句的方法&#xff0c;我们的解决方案可能如下…

java数据库编程——执行查询操作(一)

【0】README 1&#xff09; 本文部分文字描述和source code 均转自 core java volume 2 &#xff0c; 旨在理解 java数据库编程——执行查询操作 的基础知识 &#xff1b; 2&#xff09; 本文和 java数据库编程——执行查询操作&#xff08;二&#xff09; 是姊妹篇&#xff…

Shell入门(九)之字符串比较

一、字符串比较 字符串比较符&#xff1a;、!、-z、-n、str 实际上&#xff0c;shell不区分数值与字符串类型&#xff0c;数值也可以使用上面比较。 a"mk" b"maokun" 运算符说明举例检测两个字符串是否相等&#xff0c;相等返回 true。[ $a $b ] 返回…

java中将毫秒转换成时间_在Java中将时间单位转换为持续时间

java中将毫秒转换成时间java.util.concurrent.TimeUnit以给定的粒度单位表示Java中的持续时间&#xff0c;并提供跨单位转换的实用方法。 java.util.concurrent.TimeUnit最早是在Java早期&#xff08;1.5&#xff09;引入的&#xff0c;但自那时以来已经扩展了好几次。 在此博客…

java数据库编程——执行查询操作(二)

【0】README 1&#xff09; 本文部分文字描述和source code 均转自 core java volume 2 &#xff0c; 旨在理解 java数据库编程——执行查询操作&#xff08;二&#xff09; 的基础知识 &#xff1b; 2&#xff09; 本文和 java数据库编程——执行查询操作&#xff08;一&…

Shell入门(十)之echo

一、echo参数 echo [参数选项] 字符串 参数选项 -e 解析字符串中的转义字符&#xff0c;如\n -E 这是默认设置&#xff0c;不解析转义字符 -n 不输出换行&#xff0c;可以使用echo -e 字符串"\c" 代替 #!/bin/bash a"abc\n" echo $a echo -e…

vaadin_Vaadin提示:延迟加载和商品标识

vaadin延迟加载 在Vaadin中使用网格&#xff0c;树或任何其他多值组件时&#xff0c;您通常希望显示数据库表中的数据&#xff0c;并且通常数据库中有多行。 在这种情况下&#xff0c;加载数千甚至数百万条记录是没有意义的&#xff0c;这将是一个巨大的性能问题。 对于此用例&…

com.mysql.jdbc.NotUpdatable: Result Set not updatable (references no primary keys).(解决方法)

【1】异常详细信息 com.mysql.jdbc.NotUpdatable: Result Set not updatable (references no primary keys). This result set must come from a statement that was created with a result set type of ResultSet.CONCUR_UPDATABLE, the query must select only one table, …

jdk 取整数_JDK 15中的确切绝对整数

jdk 取整数JDK 15 Early Access Build b18向Math和StrictMath类引入了新方法&#xff0c;这些方法将在提供的值超出方法所支持的范围时抛出ArithmeticException &#xff0c;而不会溢出。 这些方法为Java中的“绝对值”概念带来了Math.addExact &#xff0c; Math.subtractExac…