JNI 學(xué)習(xí)筆記(二)-- JNI訪問Java中各方法

版權(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);

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末癌佩,一起剝皮案震驚了整個(gè)濱河市现斋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌恬砂,老刑警劉巖帚称,帶你破解...
    沈念sama閱讀 223,002評(píng)論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件官研,死亡現(xiàn)場(chǎng)離奇詭異秽澳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)戏羽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門担神,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蛛壳,你說我怎么就攤上這事杏瞻。” “怎么了衙荐?”我有些...
    開封第一講書人閱讀 169,787評(píng)論 0 365
  • 文/不壞的土叔 我叫張陵捞挥,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我忧吟,道長(zhǎng)砌函,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,237評(píng)論 1 300
  • 正文 為了忘掉前任溜族,我火速辦了婚禮讹俊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘煌抒。我一直安慰自己仍劈,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,237評(píng)論 6 398
  • 文/花漫 我一把揭開白布寡壮。 她就那樣靜靜地躺著贩疙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪况既。 梳的紋絲不亂的頭發(fā)上这溅,一...
    開封第一講書人閱讀 52,821評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音棒仍,去河邊找鬼悲靴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛莫其,可吹牛的內(nèi)容都是我干的癞尚。 我是一名探鬼主播,決...
    沈念sama閱讀 41,236評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼榜配,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼否纬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蛋褥,我...
    開封第一講書人閱讀 40,196評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎睛驳,沒想到半個(gè)月后烙心,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膜廊,經(jīng)...
    沈念sama閱讀 46,716評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,794評(píng)論 3 343
  • 正文 我和宋清朗相戀三年淫茵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了爪瓜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,928評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匙瘪,死狀恐怖铆铆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丹喻,我是刑警寧澤薄货,帶...
    沈念sama閱讀 36,583評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站碍论,受9級(jí)特大地震影響谅猾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鳍悠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,264評(píng)論 3 336
  • 文/蒙蒙 一税娜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧藏研,春花似錦敬矩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至袒哥,卻和暖如春缩筛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背堡称。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工瞎抛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人却紧。 一個(gè)月前我還...
    沈念sama閱讀 49,378評(píng)論 3 379
  • 正文 我出身青樓桐臊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親晓殊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子断凶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,937評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容