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
// 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; } }