Java通过JNI调用本地C/C++程序--常用示例

来源:互联网 发布:网络交友的利弊 编辑:程序博客网 时间:2024/05/21 10:45

Java通过JNI调用本地C/C++程序--常用示例

         关于java调用本地c/c++程序,流程及简单示例可以参考《Java通过JNI调用本地C或C++程序》,下面列举下常用到的示例。

1创建java类,及native方法

package com.supre.test;public class Position {static{System.load(System.getProperty("user.dir")+"/lib/position.dll");}public native void test1();public static native int test2(int a);public native String test3(String b);public native Teacher test4(Student stu);    public native List<Teacher> test5(List<Student> stus);}
package com.supre.test;public class Student {private int stuNo;private String stuName;public int getStuNo() {return stuNo;}public void setStuNo(int stuNo) {this.stuNo = stuNo;}public String getStuName() {return stuName;}public void setStuName(String stuName) {this.stuName = stuName;}public Student(int stuNo, String stuName) {super();this.stuNo = stuNo;this.stuName = stuName;}}
package com.supre.test;public class Teacher {private int teaNo;private String teaName;public int getTeaNo() {return teaNo;}public void setTeaNo(int teaNo) {this.teaNo = teaNo;}public String getTeaName() {return teaName;}public void setTeaName(String teaName) {this.teaName = teaName;}@Overridepublic String toString() {return "Teacher [teaNo=" + teaNo + ", teaName=" + teaName + "]";}}
package com.supre.test;public class Test {public static void main(String[] args) {Position p = new Position();p.test1();int a = Position.test2(3);String b = p.test3("test");Teacher t = p.test4(new Student(1, "aaa"));List<Student> stus = new ArrayList<Student>();stus.add(new Student(1, "11"));stus.add(new Student(2, "22"));stus.add(new Student(3, "33"));stus.add(new Student(4, "44"));List<Teacher> ts = p.test5(stus);System.out.println(a);System.out.println(b);System.out.println(t);for (Teacher teacher : ts) {System.out.println(teacher);}}}

2.生产Position类的.h文件position.h,该文件为参考用,主要实现文件中声明的方法(方法参考《Java通过JNI调用本地C或C++程序》)

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_supre_test_Position */#ifndef _Included_com_supre_test_Position#define _Included_com_supre_test_Position#ifdef __cplusplusextern "C" {#endif/* * Class:     com_supre_test_Position * Method:    test1 * Signature: ()V */JNIEXPORT void JNICALL Java_com_supre_test_Position_test1  (JNIEnv *, jobject);/* * Class:     com_supre_test_Position * Method:    test2 * Signature: (I)I */JNIEXPORT jint JNICALL Java_com_supre_test_Position_test2  (JNIEnv *, jobject, jint);/* * Class:     com_supre_test_Position * Method:    test3 * Signature: (Ljava/lang/String;)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_supre_test_Position_test3  (JNIEnv *, jobject, jstring);/* * Class:     com_supre_test_Position * Method:    test4 * Signature: (Lcom/supre/test/Student;)Lcom/supre/test/Teacher; */JNIEXPORT jobject JNICALL Java_com_supre_test_Position_test4  (JNIEnv *, jobject, jobject);/* * Class:     com_supre_test_Position * Method:    test5 * Signature: (Ljava/util/List;)Ljava/util/List; */JNIEXPORT jobject JNICALL Java_com_supre_test_Position_test5  (JNIEnv *, jobject, jobject);#ifdef __cplusplus}#endif#endif
3.实现position.h中的方法,并生成动态库.dll文件(linux为.so文件)
// position.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "position.h"JNIEXPORT void JNICALL Java_com_supre_test_Position_test1(JNIEnv * env, jobject position){printf("test1");}JNIEXPORT jint JNICALL Java_com_supre_test_Position_test2(JNIEnv * env, jobject position, jint a){return a+3;}JNIEXPORT jstring JNICALL Java_com_supre_test_Position_test3(JNIEnv * env, jobject position, jstring a){jstring r = env->NewStringUTF((char *)"test333");return r;}JNIEXPORT jobject JNICALL Java_com_supre_test_Position_test4(JNIEnv * env, jobject position, jobject stu){jclass stuCla = env->FindClass("com/supre/test/Student");jfieldID stuName = env->GetFieldID(stuCla,"stuName","Ljava/lang/String;");jobject stuNameV = env->GetObjectField(stu,stuName);jclass teaCla = env->FindClass("com/supre/test/Teacher");jmethodID setNo = env->GetMethodID(teaCla,"setTeaNo","(I)V");jmethodID setName = env->GetMethodID(teaCla,"setTeaName","(Ljava/lang/String;)V");jobject tea = env->NewObject(teaCla,setNo,setName);jfieldID teaNo = env->GetFieldID(teaCla,"teaNo","I");jfieldID teaName = env->GetFieldID(teaCla,"teaName","Ljava/lang/String;");env->SetObjectField(tea,teaName,stuNameV);env->SetIntField(tea,teaNo,2);return tea;}JNIEXPORT jobject JNICALL Java_com_supre_test_Position_test5(JNIEnv * env, jobject position, jobject stus){int i;jclass clz_stu = env->FindClass("Lcom/supre/test/Student;");jclass clz_teac = env->FindClass("Lcom/supre/test/Teacher;");jclass clz_list = env->FindClass("Ljava/util/ArrayList;");jmethodID list_get = env->GetMethodID(clz_list,"get","(I)Ljava/lang/Object;");jmethodID list_size = env->GetMethodID(clz_list,"size","()I");jmethodID list_add = env->GetMethodID(clz_list,"add","(Ljava/lang/Object;)Z");jmethodID list_init = env->GetMethodID(clz_list,"<init>","()V");jint len = env->CallIntMethod(stus,list_size);jobject teas = env->NewObject(clz_list,list_init);for (i=0;i<len;i++){ jobject obj_stu = env->CallObjectMethod(stus,list_get,i); jint stuNo = env->GetIntField(obj_stu,env->GetFieldID(clz_stu,"stuNo","I")); jobject stuName = env->GetObjectField(obj_stu,env->GetFieldID(clz_stu,"stuName","Ljava/lang/String;"));  jobject obj_teac = env->NewObject(clz_teac,env->GetMethodID(clz_teac,"<init>","()V")); env->SetIntField(obj_teac,env->GetFieldID(clz_teac,"teaNo","I"),stuNo); env->SetObjectField(obj_teac,env->GetFieldID(clz_teac,"teaName","Ljava/lang/String;"),stuName); env->CallBooleanMethod(teas,list_add,obj_teac);}return teas;}

4.将生产的动态库文件,拷贝到Position类中静态块中加载的路径(System.getProperty("user.dir")+"/lib/position.dll")下,这个路径只要java代码能加载到就行,然后运行Test类中的main方法,结果如下:

6test333Teacher [teaNo=2, teaName=aaa]Teacher [teaNo=1, teaName=11]Teacher [teaNo=2, teaName=22]Teacher [teaNo=3, teaName=33]Teacher [teaNo=4, teaName=44]test1

参考博文:http://www.cnblogs.com/andtt/articles/2145574.html

http://blog.csdn.net/qinjuning/article/details/7607214







原创粉丝点击