JNI实现Java与C/C++交互的核心:native
1、在Java类中声明好双方交互的接口,用native修饰;
2、通过javac Xxx.java生成 Xxx.class文件;
3、通过javah Xxx生成Xxx.h文件;
4、在.cpp中实现native方法(可以调用本地其它C/C++方法);
5、编译生成lib库,Mac终端命令:g++ -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/include xxxxxx.cpp -o libhi.jnilib;(libhi--hi为库名)
6、运行java Xxx。
-------》〉》〉在C/C++中调用Java时,应先将JVM注册到当前线程,代码如下:
声明全局变量:
- JavaVM* g_jvm = NULL;
- jobject jni_obj;
初始化:
- env->GetJavaVM(&g_jvm);
- jni_obj = env->NewGlobalRef(obj);
在当前C/C++方法中注册JVM:
- JNIEnv* jni_env;
- g_jvm->AttachCurrentThread(&jni_env, NULL);
下面资源先标记下,以后有时间再细写。
----------------------------------------------------------------------------------------------------
Mark:
一、jni.h头文件资源:
https://github.com/mapbox/jni.hpp/blob/master/test/openjdk/jni.h
——————————————————————————————————————————————
二、非常好的博客,讲解很详细,文末附有官方文档链接
http://www.cnblogs.com/likwo/archive/2012/05/21/2512400.html
——————————————————————————————————————————————
三、文末有IBM的技术原文链接(规范使用JNI)https://blog.csdn.net/ostrichmyself/article/details/4557851
——————————————————————————————————————————————
四、源自:https://blog.csdn.net/zddblog/article/details/8661095
jclass list_cls = env->FindClass("Ljava/util/ArrayList;");
jmethodID list_costruct = env->GetMethodID(list_cls , "<init>","()V");
jobject list_obj = env->NewObject(list_cls , list_costruct);
//获得该类型的构造函数 函数名为 <init> 返回类型必须为 void 即 V
//第三个参数根据构造函数的类型设定
//例如:"(Ljava/lang/String;F)V"表示Java中方法为void xxx(String, float)其中,xxx表示函数名
//-------------------------------------------------
//基本JNI域描述符
// Z -- boolean
// B -- byte
// C -- char
// S -- short
// I -- int
// J -- long
// F -- Float
// D -- double
//引用类型的描述符
// Object -- Ljava/lang/Object; //注意此处的分号(;)是JNI的一部分,不能省。
// String -- Ljava/lang/String;
// int[] -- [I
// float[] -- [F
// String[] -- [Ljava/lang/String;
//方法表示示例
// int f (int i, Object object) -- (ILjava/lang/Object;)I
//void set (byte[ ] bytes) -- ([B)V
- //jstring to char*
- char* jstringTostring(JNIEnv* env, jstring jstr)
- {
- char* rtn = NULL;
- jclass clsstring = env->FindClass("java/lang/String");
- jstring strencode = env->NewStringUTF("utf-8");
- jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
- jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
- jsize alen = env->GetArrayLength(barr);
- jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
- if (alen > 0)
- {
- rtn = (char*)malloc(alen + 1);
- memcpy(rtn, ba, alen);
- rtn[alen] = 0;
- }
- env->ReleaseByteArrayElements(barr, ba, 0);
- return rtn;
- }
- //char* to jstring
- jstring stringToJstring(JNIEnv* env, const char* pat)
- {
- jclass strClass = env->FindClass("Ljava/lang/String;");
- jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
- jbyteArray bytes = env->NewByteArray(strlen(pat));
- env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
- jstring encoding = env->NewStringUTF("utf-8");
- return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
- }
- char* bytesToChars(JNIEnv* env, jbyteArray byteArr)
- {
- jbyte* bytes;
- bytes = env->GetByteArrayElements(byteArr, 0);
- int len = env->GetArrayLength(byteArr);
- char* chars = new char[len+1];
- memset(chars,0,len+1);
- memcpy(chars,bytes,len);
- chars[len] = 0;
- env->ReleaseByteArrayElements(byteArr, bytes, 0);
- return chars;
- }
———————————————————————————————————————————————————
五、JNI内存泄漏分析:https://blog.csdn.net/renxianzuo/article/details/6824716
————————————————————————————————————————————
六、该博文集合了很多JNI资料,很杂,Chapter6、7讲的不错,目前只看到Chapter7,前面可直接忽略 https://blog.csdn.net/taily_duan/article/details/52816504