Linux安全网 - Linux操作系统_Linux 命令_Linux教程_Linux黑客

会员投稿 投稿指南 本期推荐:
搜索:
您的位置: Linux安全网 > Linux编程 > » 正文

Step By Step(Java 本地方法篇)(6)

来源: 未知 分享至:
return ret;
27 }

    在VC中调试C语言的DLL:
    就像开篇中提到的,跨语言开发势必会给后期的程序调试带来一定的麻烦,特别是在需要调试本地库代码的时候,这时我们有多个选择来调试我们的程序,如输出日志,基于IDE的Debug等,很明显后者会是我们的首选。下面就将介绍一下如何在IDE中调试本地库的代码,我们这里只是以VC为例,至于Linux下的gcc,其方法基本相同。
    1)    我们现在假设调用Java本地方法的测试代码已经可以执行,也不会抛出UnsatisfiedLinkError的异常,只是在程序运行的过程中native方法出现逻辑错误,或是一些指针操作的错误。
    2)    这里我使用的是Visual Studio 2005,如果打算利用VC的IDE调试本地库代码,需要在VC中进行一些必要的配置,以便Java的程序能够拉起该DLL。
    3)    鼠标右键点击\"解决方案资源管理器\"窗口中的工程名称,如\"Print\",选择弹出菜单中的\"属性\"条目,弹出工程的属性页。
    4)    点击右侧的\"调试\",然后在左侧的\"命令\"中填入C:Program FilesJavajdk1.6.0_23binjava,在\"命令参数\"中填入\"MyTest\"(结合上面的示例),最后在\"工作目录\"中填入\"DLL工程路径debug\",如\"D:HelloNativedebug\"。
    5)    将eclipse工程路径下bin文件夹(如:D:ProgramsJava ProgramsWorkspaceMyTestbin)的类文件拷贝到DLL工程路径debug下(如:D:HelloNativedebug)。
    6)    由于从java.exe启动,单步调试是汇编代码,所以要在调试的函数中设置断点,运行到断点处再单步调试。
    6.    访问域:
    这个代码示例和前面的示例将会有两点主要差异,一是native方法不在是static方法,而是普通的对象方法,再者就是C语言中的代码将会利用JNI提供的C接口访问Java对象中域字段的信息。
    1)    含有native方法的Java代码:

 1     public class Employee {
2 public Employee(String n,double s) {
3 name = n;
4 salary = s;
5 }
6 public native void raiseSalary(double byPercent);
7 public void print() {
8 System.out.println(name + \" \" + salary);
9 }
10 private String name;
11 private double salary;
12 static {
13 System.loadLibrary(\"Employee\");
14 }
15 }

    2)  实现本地方法的C语言代码:

 1     #include \"Employee.h\"
2 #include <stdio.h>
3
4 //1. 由于该示例的native方法为非静态non-static域方法,而是普通的域方法。
5 //该对应函数的第二个参数也由静态方法中jclass改为jobject,可以将其视为this。
6 JNIEXPORT void JNICALL Java_Employee_raiseSalary
7 (JNIEnv* env, jobject this_obj, jdouble byPercent)
8 {
9 //2.获取this对象的Class对象,如Java代码中的getClass()方法。
10 jclass class_Employee = env->GetObjectClass(this_obj);
11 //3.获取域字段的结构体,使用方式和Java中通过反射获取Class的域字段如出一辙。
12 //最后一个参数\"D\",表示域字段的类型,D表示double,后面会给出详细的列表。
13 jfieldID id_salary = env->GetFieldID(class_Employee,\"salary\",\"D\");
14 //4.JNI中为了保证JVM的安全,不允许C语言中的代码直接访问Java类中的数据,
15 //这样可以避免暴露JVM中对象布局的细节,而是提供了一组JNI接口函数访问域字段。
16 //这里由于salary是double类型,如果是int类型的域字段可以调用GetIntField函数
17 //获得,不同的域字段类型以此类推。
18 jdouble salary = env->GetDoubleField(this_obj,id_salary);
19 salary *=

Tags:
分享至:
最新图文资讯
1 2 3 4 5 6
验证码:点击我更换图片 理智评论文明上网,拒绝恶意谩骂 用户名:
关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 发展历史