導航:首頁 > 編程語言 > charjstring轉換

charjstring轉換

發布時間:2023-08-21 18:44:00

A. JNI編程之如何傳遞參數(一)——String參數的傳遞

先看一個例子,class Prompt { // native method that prints a prompt and reads a line private native String getLine(String prompt); public static void main(String args[]) { Prompt p = new Prompt(); String input = p.getLine("Type a line: "); System.out.println("User typed: " +input); } static { System.loadLibrary("Prompt"); } }在這個例子中,我們要實現一個native方法 String getLine(String prompt); 讀入一個String參數,返回一個String值。通過執行javah -jni得到的頭文件是這樣的#include<jni.h> #ifndef_Included_Prompt #define_Included_Prompt #ifdef __cplusplus extern"C" { #endif JNIEXPORT jstringJNICALL Java_Prompt_getLine(JNIEnv *env, jobject this, jstring prompt); #ifdef __cplusplus } #endif #endifjstring是JNI中對應於String的類型,但是和基本類型不同的是,jstring不能直接當作C++的string用。如果你用 cout << prompt << endl; 編譯器肯定會扔給你一個錯誤信息的。其實要處理jstring有很多種方式,這里只講一種我認為最簡單的方式,看下面這個例子,#include"Prompt.h" #include<iostream> JNIEXPORT jstringJNICALL Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt) { const char* str; str = env->GetStringUTFChars(prompt, false); if(str == NULL) { return NULL; /* OutOfMemoryError already thrown */ } std::cout << str << std::endl; env->ReleaseStringUTFChars(prompt, str); char* tmpstr = "return string succeeded"; jstring rtstr = env->NewStringUTF(tmpstr); return rtstr; }在上面的例子中,作為參數的prompt不能直接被C++程序使用,先做了如下轉換 str = env->GetStringUTFChars(prompt, false); 將jstring類型變成一個char*類型。返回的時候,要生成一個jstring類型的對象,也必須通過如下命令,

B. jni問題:返回NewStringUTF的jstring 是由jvm管理還是需要手動釋放

有個需求,需要jni中返回jstring,由於一直在c++中使用string拼接字元串,所以返回得把string轉成jstring,網上搜了下,非常麻煩,再加上我返回jstring用的統一介面是
env->NewStringUTF(result)
env為jni指針,result為const char*
所以想到先把string轉成const char*,然後直接調用這個介面返回string,代碼如下:

string str = "";
result = str.c_str();
return env->NewStringUTF(result);
如此編譯so運行之後確實起初沒發現沒問題,本來也以為此方案OK,但是在紅米note2上發現返回亂碼,分析得知str.c_str()返回的指針會由於str的被回收而導致指向垃圾內容。如此一來轉換解決方案如下:

char* c;
const int len = str.length();
c =new char[len+1];
strcpy(c,str.c_str());
const char* result = c;
return result;
如此將str里的內容賦值給一個const char*即可。

C. 在JNI中如何將jobject類型轉換為jdouble類型

#include<jni.h>
#include"com_test_Test.h"
#include<stdio.h>
#include<stdlib.h>
#include<strings.h>

//獲取字元串
JNIEXPORTvoidJNICALLJava_com_test_Test_sayHello(JNIEnv*env,jobjectobj,
jstrings){

char*str=(char*)(*env)->GetStringUTFChars(env,s,0);
printf(" c-string:hello-%s",str);

}

//獲取,返回int
JNIEXPORTjintJNICALLJava_com_test_Test_add(JNIEnv*env,jobjectobj,
jinta,jintb){
inti=a;
intj=b;
printf(" c-int:%d-%d",i,j);
charstr[256];
sprintf(str,"%d",i+j);
return(jint)i+j;
}

//獲取,返回float
JNIEXPORTjfloatJNICALLJava_com_test_Test_getFloat(JNIEnv*env,jobjectobj,
jfloatf){
floatfl=f;
printf(" c-float:%3f",fl);

fl=200.555;
return(jfloat)fl;
}

//獲取,返回double
JNIEXPORTjdoubleJNICALLJava_com_test_Test_getDouble(JNIEnv*env,
jobjectobj,jdoubledou){
doubled=dou;
printf(" c-double:%3f",d);

d=800.88;
return(jdouble)d;
}

//獲取,返回boolean
JNIEXPORTjbooleanJNICALLJava_com_test_Test_getBoolean(JNIEnv*env,
jobjectobj,jbooleanbool){

unsignedcharb=bool;
printf(" c-boolean:%lu",b);
if(b){
printf("true");
}else{
printf("false");
}

b=1;
return(jboolean)b;
}

//獲取,返回string
JNIEXPORTjstringJNICALLJava_com_test_Test_getString(JNIEnv*env,
jobjectobj,jstrings){
char*st=(char*)(*env)->GetStringUTFChars(env,s,0);
printf(" c-string:%s",st);

char*str="hellowangwu!";
jstringrtn;
rtn=(*env)->NewStringUTF(env,str);
returnrtn;
}

//獲取,返回string[]
_com_test_Test_getStringArray(JNIEnv*env,
jobjectobj,jobjectArrayarr){
intlen=(*env)->GetArrayLength(env,arr);
printf(" c-stringArray:");
inti=0;
for(i=0;i<len;i++){
jobjectobj=(*env)->GetObjectArrayElement(env,arr,i);
jstringstr=(jstring)obj;
constchar*szStr=(*env)->GetStringUTFChars(env,str,0);
printf("%d-%s",i,szStr);
(*env)->ReleaseStringChars(env,str,szStr);
}
//-----返回----

jstringstr;
jobjectArrayargs=0;
jsizesize=5;
char*sa[]={"Hello,","world!","zhang","san","yuang"};
intj=0;
jclassobjClass=(*env)->FindClass(env,"java/lang/String");
args=(*env)->NewObjectArray(env,size,objClass,0);
for(j=0;j<size;j++){
str=(*env)->NewStringUTF(env,sa[j]);
(*env)->SetObjectArrayElement(env,args,j,str);
}
returnargs;
}

-----------------------------------------------------------------

下面是Test.java

packagecom.test;

publicclassTest{
privatenativevoidsayHello(Stringstr);

privatenativeintadd(inta,intb);

privatenativefloatgetFloat(floatf);

privatenativedoublegetDouble(doubled);

(booleanb);

privatenativeStringgetString(Stringstr);

privatenativeString[]getStringArray(String[]sa);

static{
System.loadLibrary("Test");
}

publicstaticvoidmain(String[]args){
Testtest=newTest();
test.sayHello("zhangsan");
System.out.println("int-->"+test.add(10,20));
System.out.println("float-->"+test.getFloat((float)20.123));
System.out.println("double-->"+test.getDouble(100.369));
System.out.println("boolean-->"+test.getBoolean(true));
System.out.println("string-->"+test.getString("wangWu"));

String[]ss={"hello","-","zhang","san"};
Object[]obj=test.getStringArray(ss);
System.out.print("string[]-->");
for(Objectobject:obj){
System.out.print(object+"");
}

}

}

D. c++ 中怎麼講jstring 轉換為 String(java中的類型)

他們倆是一個類型只不過一個是封裝類而已就如同 int 和interger

E. C++ 數字轉字元串 double 轉換成字元串 就是char類型的 或者是 jstring也行

可以有好幾種方法,比如dbl為那個double變數:
c的方法:
char buffer[32];
snprintf(buffer, 32, "%g", dbl);

boost方法:
std::string str = boost::lexical_cast<std::string>(dbl);

stringstream方法:
std::ostringstream strs;
strs << dbl;
std::string str = strs.str();

F. 怎麼把jstring轉換成char

//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 stoJstring(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);
}

G. 將const char類型轉換成jstring類型中的 NewStringUTF("GB2312");是何含義

jstring
encoding
=
(env)->NewStringUTF("GB2312");
這句只是得到一個內容為「GB2312」的jstring字元串而已,因為這個字元串後面NewObject創建jstring時,jstring的構造函數需要用到(想想你在JAVA里將byte數組轉換為一個GB2312編碼的String會怎麼做,你會需要在構造函數那明確寫一個「GB2312「這樣的參數)。
總而言之,你這里給出的所有代碼的目的就是:將一個C語言中的char*字元串轉換為編碼為GB2312的JAVA字元串(在JNI中用jstring代表)並返回。

H. 如何解決jni char轉化為jstring亂碼問題

java內部是使用16bit的unicode編碼(UTF-16)來表示字元串的,無論中文英文都是2位元組; jni內部是使用UTF-8編碼來表示字元串的,UTF-8是變長編碼的unicode,一般ascii字元是1位元組,中文是3位元組; c/c++使用的是原始數據,ascii就是一個位元組了,中文一般是GB2312編碼,用兩個位元組來表示一個漢字。
明確了概念,操作就比較清楚了。下面根據字元流的方向來分別說明一下
1、java --> c/c++
這種情況中,java調用的時候使用的是UTF-16編碼的字元串,jvm把這個字元串傳給jni,c/c++得到的輸入是jstring,這個時候,可以利用jni提供的兩種函數,一個是GetStringUTFChars,這個函數將得到一個UTF-8編碼的字元串;另一個是 GetStringChars這個將得到UTF-16編碼的字元串。無論那個函數,得到的字元串如果含有中文,都需要進一步轉化成GB2312的編碼。

2、c/c++ --> java
jni返回給java的字元串,c/c++首先應該負責把這個字元串變成UTF-8或者UTF-16格式,然後通過NewStringUTF或者NewString來把它封裝成jstring,返回給java就可以了。
如果字元串中不含中文字元,只是標準的ascii碼,那麼使用GetStringUTFChars/NewStringUTF就可以搞定了,因為這種情況下,UTF-8編碼和ascii編碼是一致的,不需要轉換。
但是如果字元串中有中文字元,那麼在c/c++部分進行編碼轉換就是一個必須了。我們需要兩個轉換函數,一個是把UTF8/16的編碼轉成GB2312;一個是把GB2312轉成UTF8/16。
這里要說明一下:Linux和win32都支持wchar,這個事實上就是寬度為16bit的unicode編碼UTF16,所以,如果我們的 c/c++程序中完全使用wchar類型,那麼理論上是不需要這種轉換的。但是實際上,我們不可能完全用wchar來取代char的,所以就目前大多數應用而言,轉換仍然是必須的。

二、一種轉換方法
使用wide char類型來轉換。
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;
}

閱讀全文

與charjstring轉換相關的資料

熱點內容
ntlea全域通win10 瀏覽:171
qq怎麼查看別人的收藏 瀏覽:135
地震三參數matlab程序 瀏覽:57
怎樣給優盤文件加密軟體 瀏覽:7
收拾文件有哪些小妙招 瀏覽:431
pdf文件去底網 瀏覽:253
win10重裝系統需要格式化c盤嗎 瀏覽:424
路由器trx文件 瀏覽:655
淘寶店鋪數據包怎麼做 瀏覽:195
win10鍵盤黏連 瀏覽:332
json如何生成表格 瀏覽:323
怎麼修復sql資料庫表 瀏覽:40
微信微博差別 瀏覽:163
簽到積分換禮品app 瀏覽:812
mfc最近打開文件 瀏覽:672
app埋點平台都有哪些app 瀏覽:314
瑞斯康達網路管理界面 瀏覽:254
ca證書管理器linux 瀏覽:358
蘋果id安全提示問題3個字元 瀏覽:949
iphone上好的拍照軟體 瀏覽:579

友情鏈接