版權(quán)聲明:著作權(quán)歸作者所有蜈出。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處轰坊。我的CSDN地址:http://blog.csdn.net/urrjdg
本文CSDN地址:http://blog.csdn.net/urrjdg/article/details/78158959
CSDN 和 簡(jiǎn)書 同步更新
看目錄去CSDN
1. JNI 訪問 java 中的 非靜態(tài)方法
package com.zeking.jni;
import java.util.Random;
public class JniTest02 {
public native void accessMethod();
int getRandom(int max){
return new Random().nextInt(max);
}
static{
System.loadLibrary("lsn02");
}
public static void main(String[] args) {
JniTest02 jniTest02 = new JniTest02();
jniTest02.accessMethod();
}
}
#include "com_zeking_jni_JniTest02.h"
/*
* Class: com_zeking_jni_JniTest02
* Method: accessMethod
* Signature: ()V
*/
// JN訪問 java 中的 非靜態(tài)方法
JNIEXPORT void JNICALL Java_com_zeking_jni_JniTest02_accessMethod
(JNIEnv * env, jobject jobj){
jclass jclz = (*env)->GetObjectClass(env, jobj);
jmethodID jmid = (*env)->GetMethodID(env, jclz, "getRandom", "(I)I");
jint jint = (*env)->CallIntMethod(env, jobj, jmid, 200);
printf("c random: %d\n",jint);
}
2. JNI 訪問Java 中的靜態(tài)方法
package com.zeking.jni;
import java.util.Random;
import java.util.UUID;
public class JniTest02 {
public native void accessStaticMethod();
public static String getRandomUUId(){
return UUID.randomUUID().toString();
}
static{
System.loadLibrary("lsn02");
}
public static void main(String[] args) {
JniTest02 jniTest02 = new JniTest02();
jniTest02.accessStaticMethod();
}
}
/*
* Class: com_zeking_jni_JniTest02
* Method: accessStaticMethod
* Signature: ()V
*/
// JN訪問 java 中的 非靜態(tài)方法
JNIEXPORT void JNICALL Java_com_zeking_jni_JniTest02_accessStaticMethod
(JNIEnv *env, jobject jobj){
jclass jclz = (*env)->GetObjectClass(env, jobj);
jmethodID jmid = (*env)->GetStaticMethodID(env, jclz, "getRandomUUId", "()Ljava/lang/String;");
jstring uuid = (*env)->CallStaticIntMethod(env, jclz, jmid);
char * uuid_c = (*env)->GetStringUTFChars(env, uuid, NULL);
char filename[100];
sprintf(filename,"D://%s.txt",uuid_c);
FILE *fp = fopen(filename, "w");
fputs("I am Zeking", fp);
fclose(fp);
printf("文件寫入成功\n");
}
3. JNI 訪問java構(gòu)造方法
package com.zeking.jni;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
public class JniTest02 {
static{
System.loadLibrary("lsn02");
}
public native Date accessConstructor();
public static void main(String[] args) {
JniTest02 jniTest02 = new JniTest02();
jniTest02.accessConstructor();
}
}
/*
* Class: com_zeking_jni_JniTest02
* Method: accessConstructor
* Signature: ()Ljava/util/Date;
*/
// 訪問構(gòu)造方法
JNIEXPORT jobject JNICALL Java_com_zeking_jni_JniTest02_accessConstructor
(JNIEnv * env, jobject jobj){
// 通過類的路徑來從JVM 里面找到對(duì)應(yīng)的類
jclass jclz = (*env)->FindClass(env, "java/util/Date");
// jmethodid <init> 構(gòu)造方法
jmethodID jmid = (*env)->GetMethodID(env, jclz, "<init>", "()V");
// 調(diào)用 newObject 實(shí)例化Date 對(duì)象,返回值是一個(gè)jobjcct
// 為什么是jobject 不是 Date,因?yàn)?在jni 里面 數(shù)據(jù)的類型對(duì)應(yīng)的關(guān)系就是將所有的 引用類型全部轉(zhuǎn)換為jobjct
jobject date_obj = (*env)->NewObject(env, jclz, jmid);
// 得到對(duì)應(yīng)對(duì)象的方法主籍,前提是,我們?cè)L問了相關(guān)對(duì)象的構(gòu)造函數(shù)創(chuàng)建了這個(gè)對(duì)象
jmethodID time_mid = (*env)->GetMethodID(env, jclz, "getTime", "()J");
jlong time = (*env)->CallLongMethod(env, date_obj, time_mid);
printf("time : %lld \n", time);
return date_obj;
}
4. 中文
這里寫圖片描述
package com.zeking.jni;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
public class JniTest02 {
public native String chineseChars(String str);
static{
System.loadLibrary("lsn02");
}
public native Date accessConstructor();
public static void main(String[] args) {
JniTest02 jniTest02 = new JniTest02();
jniTest02.chineseChars("測(cè)試中文");
}
}
#include "stdafx.h"
#include "com_zeking_jni_JniTest02.h"
#include <Windows.h>
#include <string.h>
// 亂碼
// java使用的是
// utf - 16 16bit 2個(gè)字節(jié)
// JNI 里面使用的是
// utf - 8 unicode 可變字節(jié)的方式 英文 1個(gè)字節(jié) 逛球,中文 3個(gè)字節(jié)
// C C++
// ascii編碼千元, 中文 的編碼方式 GB2312 編碼,中文 2個(gè) 字節(jié)
/*
* Class: com_zeking_jni_JniTest02
* Method: chineseChars
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
// 中文
JNIEXPORT jstring JNICALL Java_com_zeking_jni_JniTest02_chineseChars
(JNIEnv * env, jobject jobj, jstring in){
// 方法一
jboolean iscp;
// char * c_str = (*env)->GetStringChars(env, in, NULL);
// JVM會(huì)重新開辟一個(gè)內(nèi)存然后存儲(chǔ) in的值
char * c_str = (*env)->GetStringChars(env, in, &iscp);
if (iscp == JNI_TRUE) // 傳&iscp 是為了獲取或者得到 它的返回值颤绕,判斷是否會(huì)開辟一個(gè)新的內(nèi)存(這個(gè)新內(nèi)存放著一樣的stirng值)給 c 來使用
{
printf("is copy: JNI_TRUE\n");
}
else if (iscp == JNI_FALSE)
{
printf("is copy: JNI_FALSE\n");
}
// 得到字符串的長(zhǎng)度
int length = (*env)->GetStringLength(env, in);
const jchar * jcstr = (*env)->GetStringChars(env, in, NULL);
// 有可能內(nèi)存不夠幸海,判空
if (jcstr == NULL) {
return NULL;
}
//jchar -> char
char * rtn = (char *)malloc(sizeof(char) *2 * length + 3);
memset(rtn, 0, sizeof(char) * 2 * length + 3);
int size = 0;
// 就是當(dāng)我們得到的jcstr指針變量所指的內(nèi)容全部復(fù)制到 對(duì)應(yīng)的指針里面來rtn(這個(gè)函數(shù)只有window環(huán)境才有)
size = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)jcstr, length, rtn, sizeof(char) * 2*length + 3, NULL, NULL);
/*if (size <= 0)
{
printf("size: 0 \n", rtn);
return NULL;
}*/
printf("string: %s\n", rtn);
if (rtn != NULL) {
free(rtn);
rtn = NULL;
}
(*env)->ReleaseStringChars(env, in, c_str);// JVM 使用。通知JVM c_str 所指的空間(這個(gè)內(nèi)存是jvm另外開辟的一個(gè)內(nèi)存奥务,所以要釋放)可以釋放了
return NULL;
// 方法二
// String 類中構(gòu)造函數(shù)物独,講byte[] 轉(zhuǎn)為對(duì)應(yīng)編碼的字符串
//public String(byte bytes[], Charset charset) {
// this(bytes, 0, bytes.length, charset);
//}
//char *c_str = "中文中文中文";
//jclass str_cls = (*env)->FindClass(env, "java/lang/String");
//jmethodID jmid = (*env)->GetMethodID(env, str_cls, "<init>", "([BLjava/lang/String;)V");
//
////jstring -> jbyteArray
//jbyteArray bytes = (*env)->NewByteArray(env, strlen(c_str));
//// 將Char * 賦值到 bytes
//(*env)->SetByteArrayRegion(env, bytes, 0, strlen(c_str), c_str);
//jstring charsetName = (*env)->NewStringUTF(env, "GB2312");
//return (*env)->NewObject(env, str_cls, jmid, bytes, charsetName);
}