java jni与c++互相调用

309 篇文章 5 订阅

1、student.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class cn_yws_jni_Main */

#ifndef _Included_student
#define _Included_student
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     cn_yws_jni_Main
 * Method:    jobjectProcess
 * Signature: (Lcn/yws/jni/Student;Ljava/lang/Integer;)Ljava/lang/String;
 */
 _declspec(dllexport) jstring  Java_cn_yws_jni_Main_jobjectProcess
  (JNIEnv *env, jobject, jobject, jobject);


#ifdef __cplusplus
}
#endif
#endif

2、student.cpp

// student.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "student.h"
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <Windows.h>
#include <iostream>
using namespace std;
static jobject myObj;

static JNIEnv* myEnv;

char* jstringToWindows( JNIEnv *env, jstring jstr )
{ //UTF8/16转换成gb2312
	int length = (env)->GetStringLength(jstr );
	const jchar* jcstr = (env)->GetStringChars(jstr, 0 );
	char* rtn = (char*)malloc( length*2+1 );
	int size = 0;
	size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
	if( size <= 0 )
		return NULL;
	(env)->ReleaseStringChars(jstr, jcstr );
	rtn[size] = 0;
	return rtn;
}

jstring WindowsTojstring( JNIEnv* env, const char* str )
{//gb2312转换成utf8/16
	jstring rtn = 0;
	int slen = strlen(str);
	unsigned short * buffer = 0;
	if( slen == 0 )
		rtn = (env)->NewStringUTF(str );
	else
	{
		int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
		buffer = (unsigned short *)malloc( length*2 + 1 );
		if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
			rtn = (env)->NewString(  (jchar*)buffer, length );
	}
	if( buffer )
		free( buffer );
	
	return rtn;
}

//Java_cn_yws_jni_Main_jobjectProcess


jstring  Java_cn_yws_jni_Main_jobjectProcess
(JNIEnv *env, jobject obj, jobject student, jobject flag,jobject ok)
{

	jclass clazz=myEnv->FindClass("cn/yws/jni/Main");
	//保存一个jobject实例到全局变量myObj中
	jmethodID con=myEnv->GetMethodID(clazz,"<init>","()V");//构造函数
	myObj=myEnv->NewObject(clazz,con);


	jmethodID method_id=myEnv->GetMethodID(clazz,"sayHello","(Ljava/lang/String;)V");	

	jstring param=WindowsTojstring(myEnv,"我是c++56");
		
	//调用java函数
	myEnv->CallVoidMethod(myObj,method_id,param);


	jstring str=WindowsTojstring(env,"你好测试,我是中午,hehe");
	
	return str;

}
void func2(JNIEnv *env, jobject obj, jstring str)
{
	char* data=jstringToWindows(env,str);

	printf("你好:%s\n",data);

}

static const JNINativeMethod gMethods[] = { //定义批量注册的数组,是注册的关键部分
	{"testFunc", "(Ljava/lang/String;)V", (void*)func2} // func2是在java中声明的native函数名,"()V"是函数的签名,可以通过javah获取。
};

//JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved);

//JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved);



JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)//这是JNI_OnLoad的声明,必须按照这样的方式声明
{
	//JNIEnv* env = NULL; //注册时在JNIEnv中实现的,所以必须首先获取它
	jint result = -1;

	//保存全局变量
	if(vm->GetEnv( (void**)&myEnv, JNI_VERSION_1_4) != JNI_OK) //从JavaVM获取JNIEnv,一般使用1.4的版本
		return -1;

	jclass clazz;
	static const char* const kClassName="cn/yws/jni/Main";

	clazz = (myEnv)->FindClass(kClassName); //这里可以找到要注册的类,前提是这个类已经加载到java虚拟机中。 这里说明,动态库和有native方法的类之间,没有任何对应关系。

	if(clazz == NULL)
	{
		printf("cannot get class:%s\n", kClassName);
		return -1;
	}
	


	if((myEnv)->RegisterNatives(clazz,gMethods, sizeof(gMethods)/sizeof(gMethods[0]))!= JNI_OK) //这里就是关键了,把本地函数和一个java类方法关联起来。不管之前是否关联过,一律把之前的替换掉!
	{
		printf("register native method failed!\n");
		return -1;
	}

	return JNI_VERSION_1_4; //这里很重要,必须返回版本,否则加载会失败。
}

JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)

{

	JNIEnv *env=NULL;
	if(vm->GetEnv((void**)&env,JNI_VERSION_1_4)!=JNI_OK)
	{

		return ;
	}
	jclass clazz=env->FindClass("cn/yws/jni/Main");
	jint result=env->UnregisterNatives(clazz);
	if(result!=JNI_OK)
	{

		printf("UnregisterNatives error\n");
		
	}

}
3、Main.java
package cn.yws.jni;


public class Main {

	static {
		System.loadLibrary("student");
	}
	
	public void sayHello(String name)
	{
		System.out.println("来自c++的同学,你好:"+name);
	}

	public static void main(String[] args) throws Exception {
		
		System.out.println(System.getProperty("file.encoding"));
		Main main = new Main();
		Main.Student student =new Student();
		student.id = 007;
		student.name = "yunshouhu";
		student.age = 23;
		String result = main.jobjectProcess(student, 100,"test我是中文");
		System.out.println(result);
		main.testFunc("hehe你是猪");

	}
	public native void testFunc(String str);
	
	public native String jobjectProcess(Student student, Integer flag,String ok);
	
	private static class Student{
		public Integer id;
		public String name;
		public Integer age;
	}

}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值