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;
}
@Override
public 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 __cplusplus
extern "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方法,结果如下:
6
test333
Teacher [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