java jni 调用_java jni调用过程分析

1.定义java类中的native方法,新建下面一个类

public class NativeDemo {

public static native void say(); //static的native方法

public native void sayHello(); //实例的native方法,两者的处理不一样

public static int number = 10;

int a = 2;

public void callThis(){

System.out.println("c++ call java method");

}

public static void main(String[] args) {

System.loadLibrary("NativeJni");

// NativeDemo.sayHello();

new NativeDemo().sayHello();

say();

}

}

2.进入java命令行

D:\project\workplatform.apps.demoLearnCenter\src\main\java>javah -help

用法:javah [选项]

其中 [选项] 包括:

-help 输出此帮助消息并退出

-classpath 用于装入类的路径

-bootclasspath 用于装入引导类的路径

-d 输出目录

-o 输出文件(只能使用 -d 或 -o 中的一个)

-jni 生成 JNI样式的头文件(默认)

-version 输出版本信息

-verbose 启用详细输出

-force 始终写入输出文件

使用全限定名称指定 (例

如,java.lang.Object)。

D:\project\workplatform.apps.demoLearnCenter\src\main\java>javap -help

Usage: javap ...

where options include:

-c Disassemble the code

-classpath Specify where to find user class files

-extdirs Override location of installed extensions

-help Print this usage message

-J Pass directly to the runtime system

-l Print line number and local variable tables

-public Show only public classes and members

-protected Show protected/public classes and members

-package Show package/protected/public classes

and members (default)

-private Show all classes and members

-s Print internal type signatures

-bootclasspath Override location of class files loaded

by the bootstrap class loader

-verbose Print stack size, number of locals and args for methods

If verifying, print reasons for failure

18eaea876138f5cff5979ef2531c5774.png

3.在vc++新建一个dll的控制台工程

e94bef0373904dff25ee86795fbfc5e8.png

4.在vc的工程里面导入刚才的那个NativeDemo.h的头文件,然后因为这个头文件需要引用jdk安装目录下的jni.h和jni_mt.h的两个头文件,从jdk的安装目录下的拷贝到工程里面

ca5d57a8553ff8ab8a1894e15e33b8d2.png

4.编写NativeDemo.h的头文件定义的两个类的实现(这里需要吧jni.h include的时候要改为“”,而不是<>,因为jni.h是在当前工程里面)

/* DO NOT EDIT THIS FILE - it is machine generated */

#include "jni.h"

/* Header for class NativeDemo */

#ifndef _Included_NativeDemo

#define _Included_NativeDemo

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: NativeDemo

* Method: say

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_NativeDemo_say

(JNIEnv *, jclass);

/*

* Class: NativeDemo

* Method: sayHello

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_NativeDemo_sayHello

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

c++源文件

#include "NativeDemo.h"

#include "jni.h"

#include

using namespace std;

JNIEXPORT void JNICALL Java_NativeDemo_say(JNIEnv * env, jclass jclazz) //static的方法生成的两个参数是JNIEnv * env, jclass jclazz,第二个参数代表java的类的class实例

{

jclass jclass_native = env->FindClass("NativeDemo"); //查找类的class对象,

jfieldID jfield_numberId = env->GetStaticFieldID(jclass_native,"number", "I"); //获得jclazz类的静态字段number,第三个参数代表静态变量的签名,java每种类型对应到一个签名串

jint jfield_number = env->GetStaticIntField(jclass_native, jfield_numberId);//获得jclazz类的静态变量的值

cout << jfield_number << endl; //打印静态变量的值

}

JNIEXPORT void JNICALL Java_NativeDemo_sayHello(JNIEnv *env, jobject jobj)//实例方法生成的第二个参数是jobject,代表某一个实例

{

jclass clazz = env->GetObjectClass(jobj); //获得实例jobj的class对象

jfieldID jfield_numberId = env->GetFieldID(clazz,"a", "I"); //获得这个实例的a实例变量

jint jfield_value = env->GetIntField(jobj,jfield_numberId); //获得这个实例的a实例变量的值

cout << jfield_value << endl;//打印这个实例的a实例变量的值

}

5.编译这个vc的工程,生成一个dll文件

c6ad089733adb42560f011bdfac8ffba.png

6.在我的电脑属性里面设置环境变量path增加这个dll的目录,因为java需要从path变量找到这个dll的目录

7.打开eclipse,编写调用的main函数代码

public class NativeDemo {

public static native void say(); //static的native方法

public native void sayHello(); //实例的native方法,两者的处理不一样

public static int number = 10;

int a = 2;

public void callThis(){

System.out.println("c++ call java method");

}

public static void main(String[] args) {

System.loadLibrary("NativeJni");

// NativeDemo.sayHello();

new NativeDemo().sayHello();

say();

}

}

执行这个main函数,结果如下

7562193a36f4760a69a367ed2fdd5f85.png

在java中需要使用System.loadLibrary("NativeJni");加载vc工程生成的dll文件,这里dll后缀不能加。

b43d261dab636e82d7e639a69bc096b2.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值