window下利用JNI在本地代码访问java代码

来源:互联网 发布:狗笼子淘宝 编辑:程序博客网 时间:2024/06/06 13:14

这一篇讨论在c/c++代码里生成java对象,访问修改其字段、调用其方法。编译和运行流程参见上一篇。

这里写两个java类:JniFuncMain和JniTest。

1.在JniFuncMain是主类。里面有一个静态整形字段。

2.仍然按照常规流程用static block加载dll库。

3.而且还声明了一个本地方法--注意static属性。返回一个JniTest对象。对象的构造过程在createJniObject()的本地函数调用java构造方法执行。

public class JniFuncMain{    private static int staticIntField = 200;        // 加载本地库jnifunc.dll    static{ System.loadLibrary("jnifunc");}    public static native JniTest createJniObject();    public static void main(String[] args)    {        System.out.println("[java]: createJniObject() call native method!");        JniTest jniObj = createJniObject();        jniObj.callTest();    }}class JniTest{    private int intField;        // 构造方法    public JniTest( int num )    {        intField = num;        System.out.println("[java]:JniTest' constructor been called! init intField =" + num);    }    // 此方法由本地代码调用    public int callByNative(int num)    {        System.out.println("[java]: i be called by native code! set intField = " + num);        return num;    }    public void callTest()    {        System.out.println("i be called by java code!");        return;    }}


本地c++代码实现createJniObject函数:

#include "JniFuncMain.h" // 注意用javah命令生成#include <stdio.h>JNIEXPORT jobject JNICALL Java_JniFuncMain_createJniObject(JNIEnv *env, jclass clazz){jclass targetClass;jmethodID mid;jobject newObject;jstring helloStr;jfieldID fid;jintstaticIntField;jintresult;// 获得JniFuncMain类的staticIntField变量值fid = env->GetStaticFieldID(clazz, "staticIntField", "I");staticIntField = env->GetStaticIntField(clazz, fid);printf("[cpp]get JniFuncMain private field staticIntField value\n");printf("JniFuncMain.staticIntField = %d\n", staticIntField);// 查找要访问的成员所在的类targetClass = env->FindClass("JniTest");// 查找构造方法mid = env->GetMethodID(targetClass, "<init>", "(I)V"); // 1."(I)V"是用javap反编译工具反编译JniTest的成员//  获得的签名。GetMethodID方法会根据此签名找到该方法。 //  反编译class文件命令,例子: javap -s -p 类名// 2. 第一个参数不是JNIEnv*类型是因为此代码是c++代码。原理类似于this指针。// 3. 只有获得构造方法时第2个参数是<init>,其他的,直接传入方法名称即可。// 生成JniTest对象printf("[cpp]JniTest object generate...\n");newObject = env->NewObject(targetClass, mid, 100);// 调用jniTest对象的方法返回一个值,本地打印出来mid = env->GetMethodID(targetClass, "callByNative", "(I)I");result = env->CallIntMethod(newObject, mid, 200);// 再调用一下jni设置字段的方法fid = env->GetFieldID(targetClass, "intField", "I");printf("[cpp]:set JniTest object field intField = 200\n");env->SetIntField(newObject, fid, 200);return newObject;}

结果如下:


原创粉丝点击