1. 程式人生 > >JNI中jstring 與 const char* 相互轉換函式

JNI中jstring 與 const char* 相互轉換函式

在平時的工作,經常用到jni和const型別轉換。

//將const char型別轉換成jstring型別
jstring CStr2Jstring( JNIEnv* env, const char* pat )
{
//定義java String類 strClass
jclass strClass = (env)->FindClass("Ljava/lang/String;");
//獲取java String類方法String(byte[],String)的構造器,用於將本地byte[]陣列轉換為一個新String
jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
//建立byte陣列
jbyteArray bytes = (env)->NewByteArray((jsize)strlen(pat));
//將char* 轉換為byte陣列
(env)->SetByteArrayRegion(bytes, 0, (jsize)strlen(pat), (jbyte*)pat);
//設定String, 儲存語言型別,用於byte陣列轉換至String時的引數
jstring encoding = (env)->NewStringUTF("GB2312");
//將byte陣列轉換為java String,並輸出
return (jstring)(env)->NewObject(strClass, ctorID, bytes, encoding);

}

char*   Jstring2CStr(JNIEnv*   env,   jstring   jstr) 

char*   rtn   =   NULL; 
jclass   clsstring   =   env->FindClass("java/lang/String");  
jstring   strencode   =   env->NewStringUTF("GB2312"); 
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);         //new   char[alen+1]; 
  memcpy(rtn,ba,alen); 
  rtn[alen]=0; 

env->ReleaseByteArrayElements(barr,ba,0); 
return rtn;

2.使用JNI預設的轉換函式實現

const char *dname=NULL;
dname = env->GetStringUTFChars(devName, 0)

其中devName是Jstring型別。

建議大家用第二種方法,更跨平臺。

---------------------------------------------------------------------------------例子:

1  使用的方法都在jniHelper.h中,包含吖標頭檔案

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/jni/JniHelper.h"                                    //(ctrl+F)
#endif

2  java呼叫C++

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 
 extern "C"
 {
  //  1.Java_com_newtest2_jniHelper_SendInfo  ”Java”開頭   ”com_nretest2”為包名  ”jniHelper”為對應的java檔案  ”SendInfo”為對應的方法  使用”_”連線
  //  2.(JNIEnv *env, jobject thiz, jstring info) 前2個為自帶引數, 其餘jstring info為自己的引數   出來彈出框 就Ok
  void  Java_com_u58_cocosgame_DDZ2_nativeLogin(JNIEnv* env, jobject thiz, jstring name, jstring pass)
  {
   const char *_name = env->GetStringUTFChars(name, 0) ;  //型別轉換
    
   const char* _pass = env->GetStringUTFChars(pass, 0);

   MessageBox( _name, _pass);
   
  }
 }
#endif
//}

3  C+++條用java

void  LoginScene::test_Java()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)    //斷裝置是否為Android裝置,如
 __android_log_print(ANDROID_LOG_ERROR, "LoginScene", "LoginScene::test_Java()");

 JniMethodInfo minfo;
 jobject jobj;

 //if (GETGAMEJAVAINSTANCE)  //JniHelper::getStaticMethodInfo(minfo, "com/u58/cocosgame/DDZ2","getInstance3","()Lcom/u58/cocosgame/DDZ2;")

//拿到類物件   與方法是靜態與...

if(GETGAMEJAVAINSTANCE)
 {
  //呼叫Java靜態函式,取得物件。 
  __android_log_print(ANDROID_LOG_ERROR, "LoginScene", "LoginScene::test_Java() 1");

  jobj = minfo.env->CallObjectMethod(minfo.classID, minfo.methodID);
  if (jobj != NULL)
  {
   __android_log_print(ANDROID_LOG_ERROR, "LoginScene", "LoginScene::test_Java() 2");
   jstring jname = minfo.env->NewStringUTF("this is name");
   jstring jpass = minfo.env->NewStringUTF("this is password");          //型別轉換
 
   if (JniHelper::getMethodInfo(minfo, GAMEPACKAGE, "test_Java", "(Ljava/lang/String;Ljava/lang/String;)V")) // ()V  引數+返回值
   {
    __android_log_print(ANDROID_LOG_ERROR, "LoginScene", "LoginScene::test_Java() 3");
    //呼叫java非靜態函式, 引數1:Java物件,上面已經取得   引數2:方法ID 
    //minfo.env->CallVoidMethod(jobj, minfo.methodID,jms); 
    minfo.env->CallVoidMethod(jobj, minfo.methodID, jname,jpass);     //???  voidMethod2
    log("test_Java succeed");
    minfo.env->DeleteLocalRef(jname);   //清楚空間
    minfo.env->DeleteLocalRef(jpass);
    return;
   }
   else
   {
    log("test_Java1 Fail1");
   }
  }
  else
  {
   log("test_Java1 Fail2");
  }
 }
 else
 {
  log("test_Java1 Fail3");
 }
#endif

}

例子二:

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 
 //getStaticMethodInfo,判斷Java靜態函式是否存在,並且把資訊儲存到minfo裡 
 //引數1:JniMethodInfo 
 //引數2:Java類包名+類名 
 //引數3:Java函式名稱 
 //引數4:函式引數型別和返回值型別,這裡的返回值型別是HelloCpp類的物件。寫法:L+包名+; 其他的型別請看上面的“JNI詳細教程” 

 JniMethodInfo minfo; 
 jobject jobj; 
 if(GETGAMEJAVAINSTANCE)
 { 
  //呼叫Java靜態函式,取得物件。 
  jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID); 
  if (jobj != NULL) 
  { 
   jlong  jms = lYuanbao;
   if(JniHelper::getMethodInfo(minfo,GAMEPACKAGE,"AliPayYuanbao","(J)V"))
   { 
    log("Startpay");
    //呼叫java非靜態函式, 引數1:Java物件,上面已經取得   引數2:方法ID 
    //minfo.env->CallVoidMethod(jobj, minfo.methodID,jms); 
    minfo.env->CallVoidMethod(jobj, minfo.methodID,jms); 
    log("Startpay suc");
    return;
   } 
   else
   {
    log("Startpay ...................

....
#endif
}------------------------------------------------------------------------

1  alipay支付寶庫,eclispe沒有。不會匯入;
頭: 1 刪除舊的   2 匯入新的(how 我死活不會,/因為選不中)  3重新整理 4 再次匯入(property--android-d匯入)

2      <uses-sdk android:minSdkVersion="10"/> 這個是SDk版本
Android SDk manager中又對用的最小Android作業系統,比高的都能玩

3          <activity android:name="com.u58.FlightChess.MobileTBFlightChess"
這個不是應用名字, 修改是在string.xml中。 (eciplse中res--values---)

4 NDK :是java C++ 之間橋樑。 SDk:是開發Java的。。。
5 編譯執行後: 會在 lib  bin  生成APK  + 。so
  jni資料夾下Android.mk修改這不用說,把自己工程要編譯的寫上去。
6
  不管C++ java 水貂用水都要做JNI型別轉換。
 
4 我問是不是匯入VS中:  真是傻逼 VS eclipse啥關係;沒關係

.mk 是makeFile
A LOCAL_MODULE_FILENAME := libcocosgame  模組名字(庫的名字)
整個C++/cocos2d-x都要用NDK編譯。 就是生成的DDZ2.java中。
B  用到了寫,沒用到。。。
 LOCAL_SRC_FILES    NDK編譯時用到的原始檔
 LOCAL_C_INCLUDES   NDK編譯時依賴的標頭檔案
 LOCAL_WHOLE_STATIC_LIBRARIES   依賴的靜態庫
 $(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external)  編譯標頭檔案時,找不到會從這些去尋找; 你註釋一個試試 crash
 #LOCAL_STATIC_LIBRARIES := cocos2dx_static  這是註釋
 LOCAL_MODULE_FILENAME    模組名字
 $(call my-dir)的作用就是返回當前目錄的路徑。

 C
 NDk    : 是編譯C++程式碼
 eclipse: 編譯java程式碼
 D:
  CoupleDDZ 是工程檔案。  libcocos2d是cocos庫檔案;
  編譯時順序: libcocos2d ---->JNI部分 ---》java本身的程式碼    都沒有問題才會生成APK

相關推薦

JNIjstring const char* 相互轉換函式

在平時的工作,經常用到jni和const型別轉換。 //將const char型別轉換成jstring型別 jstring CStr2Jstring( JNIEnv* env, const char* pat ) { //定義java String類 strClass j

JNI很有用的jstring const char* 的相互轉換函式

JNT中很有用的jstring 與 const char* 的相互轉換函式 我們使用JNI的時候經常碰到jstring 與 const char*轉換的問題,以及中文編碼問題,這裡從網上看到的2個比較好的相互轉換函式,今天把它摘錄下來,以備用之。呵呵。 //將const c

JavaDateString的相互轉換

獲取 org 復制 日期類型 junit clas 時間 -m see 我們在註冊網站的時候,往往需要填寫個人信息,如姓名,年齡,出生日期等,在頁面上的出生日期的值傳遞到後臺的時候是一個字符串,而我們存入數據庫的時候確需要一個日期類型,反過來,在頁面上顯示的時候,需要從數據

C/C++ASCIIUnicode字串相互轉換

轉載地址:https://blog.csdn.net/wbq2018/article/details/8806431 1、ASCII to Unicode 函式: wcstombs(VC6)、wcstombs_s 例項: //crt_wcstombs_s.c //This examp

Python字串datetime的相互轉換

1. 字串轉換成datetime物件 from datetime import datetime t = datetime.strptime(append_at, '%Y-%m-%d %H:%M:%S') 結果顯示: <class 'datetime.datetime

JS二進位制十進位制的相互轉換

十進位制轉換為二進位制: var num = 100; console.log(num.toString(2)); toString()方法可把一個 Number 物件轉換為一個字串,並返回結果。 語法 NumberObject.toString(radix); 其中,radix為可選。規

【C++】C++intstring的相互轉換

一、int轉string 1.c++11標準增加了全域性函式std::to_string: string to_string (int val); string to_string (long val); string to_string (long long val); string to_str

JSDateString的相互轉換

1- Date -> Stringnew Date().toLocaleDateString();  ==> 2017/4/152- Date -> "2017-04-15"varye

JAVA時間字串的相互轉換(工具類)

<span style="font-size:24px;">//model為字串的時間格式,如"<span style="font-family: arial; line-heigh

cocos2d-x 關於 std::string const char* 之間轉換的奇怪問題

//先儲存一個string型別資料 CCUserDefault::sharedUserDefault()->setStringForKey("Jason", "Hello"); CCUserDefault::sharedUserDefault()-&

C語言字串整數的相互轉換

C語言提供了幾個標準庫函式,可以將任意型別(整型、長整型、浮點型等)的數字轉換為字串,下面列舉了各函式的方法及其說明。 # include <stdlib.h> 將數字轉換為字串   ● itoa():將整型值轉換為字串。   ● ltoa():將長整

C/C++ 十六進位制char*Binary char*相互轉換

1. 十六進位制char* 轉 Binary char* 例如:“fedcba9876543210” 轉換為:char bin[8] ={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}形式。 程式碼: /*兩個字元轉換成

C++intstring的相互轉換

一、int轉string 1.c++11標準增加了全域性函式std::to_string: string to_string (int val); string to_string (long val); string to_string (long long val);

java物件位元組陣列相互轉換

1.首先物件要繼承Serializable介面 將位元組轉換為物件 public static Object ByteToObject(byte[] bytes) { Object obj = null; try { // bytearray to obje

PHP圖片base64字串相互轉換函式

/** * base64字串轉換成圖片 * @param string $base64_string base64字串 * @param unknown $path 圖片儲存路徑 * @param string $prefix 圖片字首 * @return boolean */ function

jnibyte[]和char*相互轉換

id= (*env)->GetFieldID(env, objectClass, filedName, "[B"); jbyteArray dataArray=(jbyteArray)((*env)-> GetObjectField(env,object,id));

C++stringchar相互轉換

一、string轉char* 1.data()方法 string str = "hello"; const char* p = str.data(); //或char * p=(char*)str.data(); 2.c_str()方法 stri

實戰c++的string系列--stringchar*、const char *的轉換(data() or c_str())

在工程中,我們也有很多時候用到string與char*之間的轉換,這裡有個一我們之前提到的函式 c_str(),看看這個原型: const char *c_str(); c_str()函式返回一個指向正規C字串的指標, 內容與本string串相同. 這

JNIjstringchar* 之間的轉換方法

在java中由於是unicode編碼,無論是英文字母還是漢字每個字元都是佔用2個位元組。但是在jni中的字元時utf-8編碼,每個字元不是等長的。所以在java和jni呼叫的時候要注意這個問題。 下面是我在網上找到的一些把jstring和char*轉換的一些sampl

c++intchar相互轉換

一、ASCII表 瞭解int與char相互轉換之前,先讓我們看一下ASCII碼錶。 其中數字字元對應的位置為:48 - 57。 二、char轉int char轉int之前,先將運算式中的每個字元都轉換成ASCII碼值,再進行計算。 以下程式碼為例,其中i3的結