本地方法(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總結
以上是生活随笔為你收集整理的本地方法(JNI)——使用调用API的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 盘点从我们电脑上消失的软件电脑上的软件消
- 下一篇: 中国最值得去的十大古镇(国内必去游玩的十