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) |