在c或c中调用java方法

上传人:xiao****1972 文档编号:84266704 上传时间:2019-03-03 格式:DOC 页数:14 大小:123.48KB
返回 下载 相关 举报
在c或c中调用java方法_第1页
第1页 / 共14页
在c或c中调用java方法_第2页
第2页 / 共14页
在c或c中调用java方法_第3页
第3页 / 共14页
在c或c中调用java方法_第4页
第4页 / 共14页
在c或c中调用java方法_第5页
第5页 / 共14页
点击查看更多>>
资源描述

《在c或c中调用java方法》由会员分享,可在线阅读,更多相关《在c或c中调用java方法(14页珍藏版)》请在金锄头文库上搜索。

1、在C或C+中调用JAVA方法JAVA跨平台的特性使JAVA越来越受开发人员的欢迎,但也往往会听到不少的抱怨:用JAVA开发的图形用户窗口界面每次在启动的时候都会跳出一个控制台窗口,这个控制台窗口让本来非常棒的程序失色不少。怎么能够让通过JAVA开发的GUI程序不弹出JAVA的控制台窗口呢?其实现在很多流行的开发环境例如JBuilder、Eclipse都是使用纯JAVA开发的集成环境,这些集成环境启动的时候并不会打开一个命令窗口,因为它使用了JNI(Java Native Interface)的技术。通过这种技术开发人员不一定要用命令行来启动JAVA程序,而可以通过编写一个本地GUI程序来直接启

2、动JAVA程序,这样就可避免另外打开一个命令窗口,让我们开发的JAVA程序更加专业。JNI允许运行在虚拟机的JAVA程序能够与其他语言(例如:C和C+)编写的程序或者库进行相互间的调用。同时JNI提供的一整套的API允许你将JAVA虚拟机直接嵌入到本地的应用程序中。下图是SUN站点上对JNI的基本结构的描述:本文将介绍如何在C/C+中调用JAVA方法并将其间可能涉及到的问题串在一起介绍整个开发的步骤以及可能遇到的难题和解决方法。本文所采用的工具是Sun Microsystems 公司创建的 Java Development Kit (JDK) 版本 1.3.1以及Microsoft 公司的Vi

3、sual C+ 6开发环境。一 环境搭建为了让本文以下部分的代码能够正常工作,我们必须建立一个完整的开发环境。首先需要下载并安装JDK1.3.1(可以http:/从下载SUN公司的JDK)。我们假设安装路径为C:JDK。下一步就是设置集成开发环境,通过Visual C+ 6的菜单Tools-Options打开选项对话框如下:将目录C:JDKinclude和C:JDKincludewin32加入到开发环境的Include Files目录中,同时将C:JDKlib目录添加到开发环境的Library Files目录中,这三个目录是JNI定义的一些常量、结构以及方法的头文件和库文件。我们的集成开发环境

4、已经设置完毕,同时为了执行程序我们需要把JAVA虚拟机所用到的动态链接库所在的目录C:JDKjrebinclassic设置到系统的PATH环境变量中。在这里需要提出一点的是:某些开发人员为了方便直接将JRE所用到的DLL文件直接拷贝到系统目录下,这样做是不行的,将导致初始化JAVA虚拟机环境失败(返回值-1),原因是JAVA虚拟机是以相对路径来寻找所用到的库文件和其他一些相关文件的。至此整个JNI的开发环境设置完毕,为了让我们的此次JNI旅程能够顺利进行我们还必须先准备一个JAVA类,在这个类中我们将用到JAVA中几乎所有有代表性的属性以及方法,例如:静态方法与属性、数组、异常抛出与捕捉等等。

5、我们定义的JAVA程序(Demo.java)如下,本文中所有的代码演示都将基于该JAVA程序。package jni.test;/* * 该类是为了演示JNI如何访问各种对象属性等 * author liudong */public class Demo /用于演示如何访问静态的基本类型属性public static int COUNT = 8;/演示对象型属性public String msg;private int counts;public Demo() this(缺省构造函数);/* * 演示如何访问构造器 */public Demo(String msg) System.out.pr

6、intln(: + msg);this.msg = msg;this.counts = null;/* * 该方法演示如何访问一个访问以及中文字符的处理 */public String getMessage() return msg;/* * 演示数组对象的访问 */public int getCounts() return counts;/* * 演示如何构造一个数组对象 */public void setCounts(int counts) this.counts = counts;/* * 演示异常的捕捉 */public void throwExcp() throws IllegalA

7、ccessException throw new IllegalAccessException(exception occur.);二 初始化虚拟机本地代码在调用JAVA方法之前必须先加载JAVA虚拟机,而后所有的JAVA程序都在虚拟机中执行。为了初始化JAVA虚拟机,JNI提供了一系列的接口函数:Invocation API。通过这些API我们可以很方便的将虚拟机加载到内存中。创建虚拟机可以用以下的函数:jint JNI_CreateJavaVM(JavaVM *pvm, void *penv, void *args);但是这个函数有一点需要注意的是在JDK1.1中第三个参数总是指向一个结构

8、JDK1_1InitArgs, 这个结构无法完全在所有版本的虚拟机中进行无缝移植。在JDK1.2中已经使用了一个标准的初始化结构JavaVMInitArgs来替代JDK1_1InitArgs。下面我们分别给出两种不同版本的示例代码。1 在JDK1.1初始化虚拟机#include int main() JNIEnv *env; JavaVM *jvm; JDK1_1InitArgs vm_args; jint res; /* IMPORTANT: 版本号设置一定不能漏 */vm_args.version = 0x00010001;/*获取缺省的虚拟机初始化参数*/ JNI_GetDefaultJ

9、avaVMInitArgs(&vm_args); /* 添加自定义的类路径 */ sprintf(classpath, %s%c%s, vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH); vm_args.classpath = classpath;/*设置一些其他的初始化参数*/ /* 创建虚拟机 */ res = JNI_CreateJavaVM(&jvm,&env,&vm_args); if (res DestroyJavaVM(jvm);2 在JDK1.2初始化虚拟机 /* invoke2.c */#include int main()

10、 int res; JavaVM *jvm; JNIEnv *env;JavaVMInitArgs vm_args;JavaVMOption options3;vm_args.version=JNI_VERSION_1_2;/这个字段必须设置为该值/*设置初始化参数*/options0.optionString = -Dpiler=NONE; options1.optionString = -Djava.class.path=.; options2.optionString = -verbose:jni;/用于跟踪运行时的信息/*版本号设置不能漏*/vm_args.version = JNI_

11、VERSION_1_2;vm_args.nOptions = 3;vm_args.options = options;vm_args.ignoreUnrecognized = JNI_TRUE;res = JNI_CreateJavaVM(&jvm, (void*)&env, &vm_args);if (res DestroyJavaVM(jvm); fprintf(stdout, Java VM destory.n);为了保证JNI代码的可移植性,建议使用JDK1.2的方法来创建虚拟机。JNI_CreateJavaVM函数的第二个参数JNIEnv *env,就是贯穿整个JNI始末的一个参数。

12、因为几乎所有的函数都要求一个参数就是JNIEnv *env。三 访问类方法初始化了JAVA虚拟机后我们就可以开始调用JAVA的方法了。要调用一个JAVA对象的方法必须经过几个步骤:1 获取指定对象的类定义(jclass)有两种途径来获取对象的类定义:第一种是在已知类名的情况下使用FindClass来查找对应的类。但是有一点要注意的是类名并不是我们平时写JAVA代码那样。例如要得到类jni.test.Demo的定义我们必须调用如下:jclass cls = (*env)-FindClass(env, jni/test/Demo);/把点号换成斜杠第二种是通过对象直接得到其所对应的类定义:jcla

13、ss cls = (*env)- GetObjectClass(env, obj);/其中obj是要引用的对象,类型是jobject 2 读取要调用方法的定义(jmethodID)我们先来看看JNI中获取方法定义的函数:jmethodID (JNICALL *GetMethodID)(JNIEnv *env, jclass clazz, const char *name, const char *sig);jmethodID (JNICALL *GetStaticMethodID)(JNIEnv *env, jclass class, const char *name, const char

14、*sig);这两个函数的区别在于一个(GetStaticMethodID)是用来获取静态方法的定义,另外一个则是获取非静态的方法定义。这两个函数都需要提供四个参数:env就是初始化虚拟机得到的JNI环境;第二个参数class是对象的类定义,也就是我们第一步得到的obj;第三个参数是方法名称;最重要的是第四个参数,这个参数是方法的定义,因为我们知道JAVA中允许方法的多态,仅仅是通过方法名并没有办法定位到一个具体的方法,因此需要第四个参数来指定方法的具体定义。但是怎么利用一个字符串来表示方法的具体定义呢?不要着急,JDK中已经为我们准备好一个反编译工具javap,通过这个工具我们就可以得到类中每个属性、方法的定义。下面我们看看jni.test.Demo的定义:

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 大杂烩/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号