不知不觉都到了第7章了,我都不好意思再讲下去了,这么个东西介绍了7章。。。这章讲完后该去实践实践了,恩。。。
Java编程语言中,使用本地方法对于程序来说是要冒很大的安全风险的。C的运行期,系统对数组越界错误,不良指针造成的间接错误不提供任何防护。所以,对于本地方法的程序员来说,处理所有的出错条件以保持Java平台的完整性显得格外重要。处理所有的出错条件以保证Java平台的完整性显得格外重要。尤其是,当你的本地方法诊断出一个它无法解决的问题时,那么它应该将此问题报告给Java虚拟机。然后,在这种情况下,很自然地会抛出一个异常。然而,C语言没有异常,必须调用Throw或ThrowNew函数来创建一个新的异常对象。当本地方法推出时,java虚拟机就会抛出该异常。
jclass class_EOFException = (*env)->FindClass(env, "java/io/EOFException");
jmethodID id_EOFException = (*env)->GetMethodID(env, class_EOFException, "<init>", ()V);
jthrowable obj_exc = (*env)->NewObject(env, class_EOFException, idEOFException);
(*env)->Throw(env, obj_exc);
通常使用ThrowNew会更加方便,只需要提供一个类和一个“改良UTF-8”字节序列,该函数就会构造一个异常对象。
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/io/EOFException"), "Unexpected end of file");
(C++中的异常和Java异常现在还没有实现,所以必须确保不能抛出C++异常,并使用上述方法抛出java异常)
因为Throw和ThrowNew都仅仅登记异常,他们不会中断本地方法的控制流,所以一般后面都会紧跟return。
if(str == null){
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/NullPointerException"), "str is NULL");
return;
}
如果本地方法调用java方法,可能要考虑java方法抛出异常。
jthrowable obj_exc = (*env)->ExceptionOcurred(env);
jboolean occurred = (*env)->ExceptionCheck(env);
如果没有任何异常挂起,第一个方法会返回NULL。第二个方法一般在不关心异常类型的情况下使用。
for(i=0; cstr[i] != 0 && !(*env)->ExceptionCheck(env); i++)
(*env)->CallVoidMethod(env, out, id_print, cstr[i]);
ok,jni基础终于介绍完了,最后一张,再来点高端的。
如果,我们有一个C或者C++程序,想要运行java代码,调用API(Invocation API)能够把Java虚拟机潜入到C或者C++程序中。下面是初始化所需的基本代码。
JavaVMOption options[1];
JavaVMInitArgs vm_args;
JavaVM *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.options = options;
JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
对JNI_CreateJavaVM的调用将创建虚拟机,并且将指针jvm指向虚拟机,指针env指向执行环境。
可以给虚拟机提供任意数目的选项,这只需增加选项数组的大小和vm_args.nOptionss的值。
当程序陷入麻烦导致程序崩溃,从而不能初始化JVM或不能装载你的类时,请打开JNI调试模式。设置一个选项如下
options[i].optionString = "-verbose:jni";
你会看到一系列说明JVM初始化进程的消息。如果看不到你装载的类,请检察官你的路径和类路径的设置。
一旦设置虚拟机,就可以入前面章节介绍的那样调用Java方法了。按照常规使用env即可。
只有在调用API中的其他函数时,才需要jvm指针,目前只有四个这样的函数。最重要的是:
(*jvm)->DestroyJavaVM(jvm);
虚拟机的启动,大家有没有想过,Android的所有程序都是跑在虚拟机上面的,他启动虚拟机的方法,也许和我们介绍的八九不离十了吧,不过也是猜测而已。
Vista对一些链接规则的改变,会导致创建JVM会有问题,可通过手工加载类库来解决。这个问题就不深入探讨,但说明创建jvm和本地系统的关系也很大。
分享到:
相关推荐
调用iphlpapi获得本地ip信息,C++源代码演示获取ip信息的全过程。
通过本地方法调用来调用C语言的例子,一个调用时间的,谨供参考
Android中调用js方法及js中调用本地方法,简单明了
注,chrome 通过注册表注册表 只能调用本地的 exe 或者bat文件,不能调用 ppt word 这样的问题,所以我用VB 写了一个exe 可以接收调用参数,这样只许注册一次就可以通过传参打开所有课执行文件了 由于1.exe是后台...
JS和Android本地方法之间的调用
【方法】html调用本地python程序进行交互 前后端交互
java调用本地打印机java调用本地打印机java调用本地打印机java调用本地打印机
web调用本地应用程序
js通过webview调用android的本地方法,避免addJavascriptInterface问题
JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式 )。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各...
jni本地调用4
delphi编程实现调用本地程序,本实例可调用本地 截图工具、步骤记录器、画图工具、计算器、记事本、屏幕键盘、放大镜、任务管理器、命令提示符、控制面板、word和excel,用的是WinExec和ShellExecute方法,需要实现...
Java本地调用接口 JNative.7z
借助WebSocket完成Android本地代码调用JavaScript代码的插件,并且可以获得返回值
该文档详细介绍了在Java代码中如何调用C或C++代码。主要思想是:将C或C++代码大包成动态链接库,然后共Java代码在执行时调用。
本地摄像头调用api
1、Dubbo 远程调用实现 2、内带zookeeper-3.4.5消息服务 3、直接导入myeclipse运行:dubbo-server导入tomcat中运行 4、dubbo-client 运行测试类/dubbo-client/src/com/fengjx/main/Consumer.java
通过Java调用本地方法.pdf