本地方法(JNI)——使用调用API
来源:互联网 发布:证书服务器开放的端口 编辑:程序博客网 时间:2024/05/29 19:40
【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; //干货——虚拟机指针jvmJNIEnv *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 _WINDOWS HINSTANCE hjvmlib; CreateJavaVM_t createJavaVM;#endif 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.options = options;#ifdef _WINDOWS hjvmlib = loadJVMLibrary(); createJavaVM = (CreateJavaVM_t) GetProcAddress(hjvmlib, "JNI_CreateJavaVM"); status = (*createJavaVM)(&jvm, (void **) &env, &vm_args);#else status = JNI_CreateJavaVM(&jvm, (void **) &env, &vm_args);#endif if (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
- 本地方法(JNI)——使用调用API
- 本地方法(JNI)——调用 java 方法
- 使用JNA替代JNI调用本地方法
- Java-----使用JNI调用本地方法
- java JNI本地方法调用的使用
- 本地方法(JNI)——从java 程序中调用C函数
- jni—编译本地方法
- Java中使用JNI调用本地动态库的方法
- 关于JNI的使用(实战linux平台下java调用本地c语言方法)
- JNI学习笔记3——本地方法取得Java属性/调用java方法
- Android使用NDK(从java调用本地函数'JNI')
- jni JAVA调用本地步骤、方法
- java 调用本地C/C++方法:jni
- 本地方法(JNI)——访问域+字符串参数
- 本地方法(JNI)——编码签名
- Android 项目中使用调用jni库调用本地C/C++方法
- Windows下使用android NDK(JNI)调用OpenCV本地代码——流程梳理
- java 使用jni调用本地c++类库
- iframe内部嵌入html页面并且能够跳转
- css实现多行文本溢出显示省略号(…)全攻略
- webView的高级用法
- UML类图关系总结
- linux之link用法
- 本地方法(JNI)——使用调用API
- 栈调用关系跟踪
- 关于编写通用API库的灵活、简洁与方便性之间的矛盾
- Android两行代码搞定ViewPager的过渡动画
- 两个editText相互监听的死循环问题
- 关于apktool反编译出错Error occured at code address 0的解决办法
- Ubuntu,Mac安装go
- TCP协议发送和接受文本消息
- Android学习-JAVA基础 (一)