c程序控制java端代码
	
整个示例程序有 jnifuncmain类(包含本地方法声明)、jnitest对象和jnifunc.dll(包含本地方法的具体实现)三部分组成。在jnifuncmain类的本地方法中调用jnitest对象的方法和成员变量,具体由c  代码实现,包含在jnifunc.dll中。
1、  编写
java代码 
jnifuncmain.java和jnitest.java
jnifuncmain.java
	
	
		
			- 
				public class jnifuncmain
 
- 
				{
 
- 
				    private static int staticintfield = 300;
 
- 
				    
 
- 
				    //加载本地库jnifunc.dll
 
- 
				    static { system.loadlibrary("jnifunc");}
 
- 
				
 
- 
				    //本地方法声明
 
- 
				    public static native jnitest createjniobject();
 
- 
				
 
- 
				    public static void main(string[] args)
 
- 
				    {
 
- 
				        //从本地代码生成jnitest对象
 
- 
				        system.out.println("[java] createjniobject()调用本地方法");
 
- 
				        try{
 
- 
				            jnitest jniobj = createjniobject();
 
- 
				            
 
- 
				            //调用jnitest对象的方法
 
- 
				            jniobj.calltest();
 
- 
				                }catch(exception e)
 
- 
				                {
 
- 
				                    system.out.println(e.getmessage());
 
- 
				                }
 
- 
				        
 
- 
				    }
 
- 
				}
			
 
 
jnitest.java
	
	
		
			- 
				class jnitest
 
- 
				{
 
- 
				    private int intfield;
 
- 
				    
 
- 
				    //构造方法
 
- 
				        public jnitest(int num)
 
- 
				        {
 
- 
				            intfield = num;
 
- 
				            system.out.println("[java}调用jnitest对象的构造方法:intfield = "  intfield);
 
- 
				        }
 
- 
				    //此方法由jni本地函数调用
 
- 
				    public int callbynative(int num)
 
- 
				    {
 
- 
				        system.out.println("[java] jnitest对象的callbynative("  num  ")调用");
 
- 
				        return num;
 
- 
				    }
 
- 
				
 
- 
				
 
- 
				    public void calltest()
 
- 
				    {
 
- 
				        system.out.println("[java] jnitest对象的calltest方法调用:intfield = "  intfield);
 
- 
				    }
 
- 
				}
			
 
 
	 2、  编译java代码
	d:\users\lusi\jni\jni-2> 
javac  jnifuncmain.java
	3、  生成c语言需要包含的头文件jnifuncmain.h
	d:\users\lusi\jni\jni-2> 
javah  jnifuncmain
	jnifuncmain.h:
	
	
		
			- 
				* do not edit this file - it is machine generated */
 
- 
				#include <jni.h>
 
- 
				/* header for class jnifuncmain */
 
- 
				
 
- 
				#ifndef _included_jnifuncmain
 
- 
				#define _included_jnifuncmain
 
- 
				#ifdef __cplusplus
 
- 
				extern "c" {
 
- 
				#endif
 
- 
				/*
 
- 
				 * class: jnifuncmain
 
- 
				 * method: createjniobject
 
- 
				 * signature: ()ljnitest;
 
- 
				 */
 
- 
				jniexport jobject jnicall java_jnifuncmain_createjniobject
 
- 
				  (jnienv *, jclass);
 
- 
				
 
- 
				#ifdef __cplusplus
 
- 
				}
 
- 
				#endif
 
- 
				#endif
			
 
 
	4、  编写c  代码 jnifunc.cpp
	
	
		
			- 
				#include "jnifuncmain.h"
 
- 
				#include <stdio.h>
 
- 
				
 
- 
				jniexport jobject jnicall java_jnifuncmain_createjniobject(jnienv * env, jclass clazz)
 
- 
				{
 
- 
				    jclass targetclass;
 
- 
				    jmethodid mid;
 
- 
				    jobject newobject;
 
- 
				    jstring hellostr;
 
- 
				    jfieldid fid;
 
- 
				    jint staticintfield;
 
- 
				    jint result;
 
- 
				
 
- 
				// c程序控制java端代码
 
- 
				
 
- 
				    //1、访问类静态成员域,获取jnifuncmain类的staticintfield变量值
 
- 
				    fid = env->getstaticfieldid(clazz, "staticintfield", "i");
 
- 
				    staticintfield = env->getstaticintfield(clazz, fid);
 
- 
				    printf("[cpp]获取jnifuncmain类的staticintfield值\n");
 
- 
				    
 
- 
				    //查找生成对象的类
 
- 
				    targetclass = env->findclass("jnitest");
 
- 
				//该函数用于加载本地定义的类。它将搜索由classpath 环境变量为具有指定名
 
- 
				//称的类所指定的目录和 zip 文件
 
- 
				// findclass的参数名必须是:类全名(即包名后跟类名,之间由“/”分隔)
 
- 
				    
 
- 
				    //2、查找构造方法
 
- 
				    mid = env->getmethodid(targetclass, "", "(i)v");
 
- 
				        // 1."(i)v"是用javap反编译工具反编译jnitest的成员
 
- 
				        // 获得的签名。getmethodid方法会根据此签名找到该方法。 
 
- 
				        // 反编译class文件命令,例子: javap -s -p 类名
 
- 
				        // 2. 第一个参数不是jnienv*类型是因为此代码是c代码。原理类似于this指针。
 
- 
				        // 3. 只有获得构造方法时第2个参数是<init>,其他的,直接传入方法名称即可。
 
- 
				    //3、生成jnitest对象(返回对象的引用)
 
- 
				    printf("[cpp]jnitest对象生成\n");
 
- 
				    newobject = env->newobject(targetclass, mid, 100);
 
- 
				    
 
- 
				    //4、调用对象的方法
 
- 
				    mid = env->getmethodid(targetclass, "callbynative", "(i)i");
 
- 
				    result = env->callintmethod(newobject, mid, 200);
 
- 
				    
 
- 
				    //5、访问对象的成员变量,设置jniobject对象的intfield值
 
- 
				    fid = env->getfieldid(targetclass, "intfield", "i");
 
- 
				    printf("[cpp]设置jnitest对象的intfield值为200\n");
 
- 
				    env->setintfield(newobject, fid, result);
 
- 
				    
 
- 
				    //返回对象的引用
 
- 
				    return newobject;
 
- 
				}
			
 
 
	5、  生成c共享库
	d:\users\lusi\jni\jni-2>
cl  -i  "d:\program
files\java\jdk1.8.0_25\include" -i  "d
	\program files\java\jdk1.8.0_25\include\win32" –ld  jnifunc.cpp  -fejnifunc.dll
	6、  执行java程序
	d:\users\lusi\jni\jni-2> java  jnifuncmain
	
                                    
            
            
              
              阅读(1376) | 评论(0) | 转发(0) |