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

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







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值