一、jbytearray轉c++byte數組 html
jbyte * arrayBody = env->GetByteArrayElements(data,0); jsize theArrayLengthJ = env->GetArrayLength(data); BYTE * starter = (BYTE *)arrayBody;
二、jbyteArray 轉 c++中的BYTE[]java
//jbytearray strIn jbyte * olddata = (jbyte*)env->GetByteArrayElements(strIn, 0); jsize oldsize = env->GetArrayLength(strIn); BYTE* bytearr = (BYTE*)olddata; int len = (int)oldsize;
三、C++中的BYTE[]轉jbyteArrayc++
//nOutSize是BYTE數組的長度 BYTE pData[] jbyte *by = (jbyte*)pData; jbyteArray jarray = env->NewByteArray(nOutSize); env->SetByteArrayRegin(jarray, 0, nOutSize, by);
四、jbyteArray 轉 char * web
char* data = (char*)env->GetByteArrayElements(strIn, 0);
五、char* 轉jstring windows
jstring WindowsTojstring(JNIEnv* env, char* str_tmp) { jstring rtn=0; int slen = (int)strlen(str_tmp); unsigned short* buffer=0; if(slen == 0) { rtn = env->NewStringUTF(str_tmp); } else { int length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str_tmp, slen, NULL, 0); buffer = (unsigned short*)malloc(length*2+1); if(MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str_tmp, slen, (LPWSTR)buffer, length) > 0) { rtn = env->NewString((jchar*)buffer, length); } } if(buffer) { free(buffer); } return rtn; }
下面這個沒有用過,剛看到,也寫進來,之後若是遇到能夠驗證下看。
六、jstring 轉 char* 或者 const char* 數組
// jstring str const char *key = env->GetStringUTFChars(str, 0); //jboolean isOffer jsClient->modify(key, isOffer); env->ReleaseStringUTFChars(str, key);
七、JNI 返回 jbyteArray 多線程
JNIEXPORT jbyteArray JNICALL Java_Test_getByteArray(JNIEnv *env, jobject obj) { jbyteArray firstMacArray = env->NewByteArray( 6 ); ...... jbyte *bytes = env->GetByteArrayElements( firstMacArray, 0); for ( int i = 0; i < sizeof( pAdapterInfo->Address ); i++ ) { bytes[ i ] = pAdapterInfo->Address[ i ]; } env->SetByteArrayRegion(firstMacArray, 0, 6, bytes ); return firstMacArray; }
八、jstring to char*ide
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); }
十、將jstring類型轉換成windows類型 .net
char* jstringToWindows( JNIEnv *env, jstring jstr ) { 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; }
十一、將windows類型轉換成jstring類型
jstring WindowsTojstring( JNIEnv* env, char* str ) { 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; } /*JNIEXPORT jstring JNICALL Java_test_cs_web_SWIFTAlianceCASmfTest_strcal (JNIEnv *env, jclass obj, jstring jstr1, jstring jstr2) { jbyteArray bytes = 0; jthrowable exc; char *pszResult = NULL; char *pszSTR1 = NULL; char *pszSTR2 = NULL; pszSTR1 = jstringTostring(env, jstr1); pszSTR2 = jstringTostring(env, jstr2); int nlen = sizeof(char)*(strlen(pszSTR1)+strlen(pszSTR2)); pszResult = (char*)malloc(nlen); strcpy(pszResult, pszSTR1); strcat(pszResult, pszSTR2); jstring jstrRe = stoJstring(env, pszResult); free(pszSTR1); free(pszSTR2); free(pszResult); return(jstrRe); } */
十二、jni object的使用
每個jni格式的dll中的object對應該java裏面的一個類。
以下例有一個 ObjData類,類中有成員bData ,Len
public class ObjData {
public byte[] bData;
public int Len;
}
//------------------------jni得到傳過來的Object類型的變量objDataIn--------
jclass clazz =(env)->FindClass("ObjData");
//從傳進來的對象中取出byte[]
jfieldID byteData = (env)->GetFieldID(clazz,"bData","[B"); jbyteArray pDataIn = (jbyteArray) (env)->GetObjectField(objDataIn, byteData); jsize theArrayLeng = env->GetArrayLength(pDataIn);
1三、byte[]轉爲BYTE[]
jbyte * arrayBody = env->GetByteArrayElements(pDataIn,0); BYTE * jDataIn = (BYTE *)arrayBody;
1四、將BYTE數組轉爲jarray
jbyte* byte = (jbyte*)jDataOut; jbyteArray jarray = env->NewByteArray(theArrayLeng); env->SetByteArrayRegion(jarray, 0, theArrayLeng, byte);
1五、給每個實例的變量賦值
(env)->SetObjectField(objDataIn,byteData,jarray); (env)->SetIntField(objDataIn,pDataInLen,jDataInLen); (env)->ReleaseByteArrayElements(pDataIn, arrayBody, 0);
1六、btye數組處理,形參做爲輸入或輸出,返回btye數組
JNIEXPORTjbyteArray JNICALL Java_com_jinhill_util_NativeModule_testByte (JNIEnv *env, jobject jo, jbyteArray jbArr) { char chTmp[] = "Hello JNI!"; int nTmpLen = strlen(chTmp); //獲取jbyteArray char *chArr = (char*)env->GetByteArrayElements(jbArr,0); //獲取jbyteArray長度 int nArrLen = env->GetArrayLength(jbArr); char *szStrBuf =(char*)malloc(nArrLen*2+10); memset(szStrBuf, 0, nArrLen*2+10); Bytes2String(chArr, nArrLen, szStrBuf,nArrLen*2+10); Trace("jbArr=%s", szStrBuf); //將jbArr做爲輸出形參 memset(chArr, 0, nArrLen); memcpy(chArr, chTmp, nTmpLen); //返回jbyteArray jbyteArray jarrRV =env->NewByteArray(nTmpLen); jbyte *jby =env->GetByteArrayElements(jarrRV, 0); memcpy(jby, chTmp, strlen(chTmp)); env->SetByteArrayRegion(jarrRV, 0,nTmpLen, jby); return jarrRV; }
1七、Java String與C char數組類型轉換實例
//String 和String[]處理 JNIEXPORTjobjectArray JNICALL Java_com_jinhill_util_NativeModule_testString (JNIEnv *env, jobject jo, jstring jstr,jobjectArray joarr) { int i = 0; char chTmp[50] = {0}; //獲取jstring值 const char* pszStr = (char*)env->GetStringUTFChars(jstr, 0); Trace("jstr=%s", pszStr); //獲取jobjectArray值 int nArrLen =env->GetArrayLength(joarr); Trace("joarr len=%d",nArrLen); for(i=0; i<nArrLen; i++) { jstring js =(jstring)env->GetObjectArrayElement(joarr, i); const char* psz = (char*)env->GetStringUTFChars(js, 0); Trace("joarr[%d]=%s",i, psz); } //將joarr做爲輸出形參 jstring jstrTmp = NULL; for(i=0; i<nArrLen; i++) { sprintf(chTmp, "No.%dHello JNI!", i); jstrTmp =env->NewStringUTF(chTmp); env->SetObjectArrayElement(joarr,i, jstrTmp); env->DeleteLocalRef(jstrTmp); } //返回jobjectArray jclass jstrCls =env->FindClass("Ljava/lang/String;"); jobjectArray jstrArray =env->NewObjectArray(2, jstrCls, NULL); for(i=0; i<2; i++) { sprintf(chTmp, "No. %dReturn JNI!", i); jstrTmp =env->NewStringUTF(chTmp); env->SetObjectArrayElement(jstrArray,i, jstrTmp); env->DeleteLocalRef(jstrTmp); } return jstrArray; }
1八、Java與C不一樣類型參數轉換實例
//不一樣類型參數處理 JNIEXPORT jintJNICALL Java_com_jinhill_util_NativeModule_testArg (JNIEnv *env, jobject jo, jint ji, jbooleanjb, jchar jc, jdouble jd) { //獲取jint型值 int i = ji; //獲取jboolean型值 BOOL b = jb; //獲取jdouble型值 double d = jd; //獲取jchar型值,Java的char兩字節 char ch[5] = {0}; int size = 0; size = WideCharToMultiByte(CP_ACP,NULL, (LPCWSTR)&jc, -1, ch, 5, NULL, FALSE); if(size <= 0) { return -1; } Trace("ji=%d,jb=%d,jc=%s,jd=%lf",i, b, ch, d); return 0; }
1九、Java 類與C結構體類型轉換實例
JNIEXPORT jint JNICALL Java_com_jinhill_util_NativeModule_setInfo (JNIEnv *env, jobject jo, jobject jobj) { char chHexTmp[512] = {0}; //將Java類轉換成C結構體 MyInfo mi; //獲取Java中的實例類Record jclass jcRec = env->FindClass("com/jinhill/util/Record"); //int id jfieldID jfid = env->GetFieldID(jcRec, "id", "I"); //String name jfieldID jfname = env->GetFieldID(jcRec, "name", "Ljava/lang/String;"); //byte[] data; jfieldID jfdata = env->GetFieldID(jcRec, "data", "[B"); //獲取Java中的實例類MyInfo jclass jcInfo = env->FindClass("com/jinhill/util/MyInfo"); //獲取類中每個變量的定義 //boolean b jfieldID jfb = env->GetFieldID(jcInfo, "b", "Z"); //char c jfieldID jfc = env->GetFieldID(jcInfo, "c", "C"); //double d jfieldID jfd = env->GetFieldID(jcInfo, "d", "D"); //int i jfieldID jfi = env->GetFieldID(jcInfo, "i", "I"); //byte[] array jfieldID jfa = env->GetFieldID(jcInfo, "array", "[B"); //String s jfieldID jfs = env->GetFieldID(jcInfo, "s", "Ljava/lang/String;"); //Record rec; jfieldID jfrec = env->GetFieldID(jcInfo, "rec", "Lcom/jinhill/util/Record;"); //獲取實例的變量b的值 mi.b = env->GetBooleanField(jobj, jfb); //獲取實例的變量c的值 jchar jc = env->GetCharField(jobj, jfc); char ch[5] = {0}; int size = 0; size = WideCharToMultiByte(CP_ACP, NULL, (LPCWSTR)&jc, -1, ch, 5, NULL, FALSE); mi.c = ch[0]; //獲取實例的變量d的值 mi.d = env->GetDoubleField(jobj, jfd); //獲取實例的變量i的值 mi.i = env->GetIntField(jobj, jfi); //獲取實例的變量array的值 jbyteArray ja = (jbyteArray)env->GetObjectField(jobj, jfa); int nArrLen = env->GetArrayLength(ja); char *chArr = (char*)env->GetByteArrayElements(ja, 0); memcpy(mi.arr, chArr, nArrLen); //獲取實例的變量s的值 jstring jstr = (jstring)env->GetObjectField(jobj, jfs); const char* pszStr = (char*)env->GetStringUTFChars(jstr, 0); strcpy(mi.sz, pszStr); //獲取Record對象 jobject joRec = env->GetObjectField(jobj, jfrec); //獲取Record對象id值 mi.rec.id = env->GetIntField(joRec, jfid); Trace("mi.rec.id=%d",mi.rec.id); //獲取Record對象name值 jstring jstrn = (jstring)env->GetObjectField(joRec, jfname); pszStr = (char*)env->GetStringUTFChars(jstrn, 0); strcpy(mi.rec.name, pszStr); //獲取Record對象data值 jbyteArray jbd = (jbyteArray)env->GetObjectField(joRec, jfdata); nArrLen = env->GetArrayLength(jbd); chArr = (char*)env->GetByteArrayElements(jbd, 0); memcpy(mi.rec.data, chArr, nArrLen); //日誌輸出 Bytes2String(mi.arr, nArrLen, chHexTmp, sizeof(chHexTmp)); Trace("mi.arr=%s, mi.b=%d, mi.c=%c, mi.d=%lf, mi.i=%d, \n mi.sz=%s\n mi.rec.id=%d, mi.rec.name=%s", chHexTmp, mi.b, mi.c, mi.d, mi.i, mi.sz, mi.rec.id, mi.rec.name); return 0; }
20、 C結構體類型與Java 類轉換實例
JNIEXPORT jobject JNICALL Java_com_jinhill_util_NativeModule_getInfo (JNIEnv *env, jobject jo) { wchar_t wStr[255] = {0}; char chTmp[] = "Hello JNI"; int nTmpLen = strlen(chTmp); //將C結構體轉換成Java類 MyInfo mi; memcpy(mi.arr, chTmp, strlen(chTmp)); mi.b = TRUE; mi.c = 'B'; mi.d = 2000.9; mi.i = 8; strcpy(mi.sz, "Hello World!"); mi.rec.id = 2011; memcpy(mi.rec.data, "\x01\x02\x03\x04\x05\x06", 6); strcpy(mi.rec.name, "My JNI"); //獲取Java中的實例類Record jclass jcRec = env->FindClass("com/jinhill/util/Record"); //int id jfieldID jfid = env->GetFieldID(jcRec, "id", "I"); //String name jfieldID jfname = env->GetFieldID(jcRec, "name", "Ljava/lang/String;"); //byte[] data; jfieldID jfdata = env->GetFieldID(jcRec, "data", "[B"); //獲取Java中的實例類 jclass jcInfo = env->FindClass("com/jinhill/util/MyInfo"); //獲取類中每個變量的定義 //boolean b jfieldID jfb = env->GetFieldID(jcInfo, "b", "Z"); //char c jfieldID jfc = env->GetFieldID(jcInfo, "c", "C"); //double d jfieldID jfd = env->GetFieldID(jcInfo, "d", "D"); //int i jfieldID jfi = env->GetFieldID(jcInfo, "i", "I"); //byte[] array jfieldID jfa = env->GetFieldID(jcInfo, "array", "[B"); //String s jfieldID jfs = env->GetFieldID(jcInfo, "s", "Ljava/lang/String;"); //Record rec; jfieldID jfrec = env->GetFieldID(jcInfo, "rec", "Lcom/jinhill/util/Record;"); //建立新的對象 jobject joRec = env->AllocObject(jcRec); env->SetIntField(joRec, jfid, mi.rec.id); jstring jstrn = env->NewStringUTF(mi.rec.name); env->SetObjectField(joRec, jfname, jstrn); jbyteArray jbarr = env->NewByteArray(6); jbyte *jb = env->GetByteArrayElements(jbarr, 0); memcpy(jb, mi.rec.data, 6); env->SetByteArrayRegion(jbarr, 0, 6, jb); env->SetObjectField(joRec, jfdata, jbarr); //建立新的對象 jobject joInfo = env->AllocObject(jcInfo); //給類成員賦值 env->SetBooleanField(joInfo, jfb, mi.b); // MultiByteToWideChar (CP_ACP, 0, mi.c, -1, wStr, 255); // env->SetCharField(joInfo, jfc, (jchar)wStr); env->SetCharField(joInfo, jfc, (jchar)mi.c); env->SetDoubleField(joInfo, jfd, mi.d); env->SetIntField(joInfo, jfi, mi.i); jbyteArray jarr = env->NewByteArray(nTmpLen); jbyte *jby = env->GetByteArrayElements(jarr, 0); memcpy(jby, mi.arr, nTmpLen); env->SetByteArrayRegion(jarr, 0, nTmpLen, jby); env->SetObjectField(joInfo, jfa, jarr); jstring jstrTmp = env->NewStringUTF(chTmp); env->SetObjectField(joInfo, jfs, jstrTmp); env->SetObjectField(joInfo, jfrec, joRec); return joInfo; }
2一、Java String與 C char數組轉換時的中文問題
//將jstring類型轉換成windows類型 char* jstringToWindows( JNIEnv *env, jstring jstr ) { 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; } //將windows類型轉換成jstring類型 jstring WindowsTojstring( JNIEnv* env, char* str ) { 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; }
2二、關於vs2015生成軟件在不一樣機器上運行缺乏庫(dll)
代碼生成->運行庫->改成「多線程(MT)」
其餘參考:
Java 經過JNI調用C或者CPP代碼
一、Java學習之經過JNI調用C/C++編寫的dll連接庫(圖文教程)
二、JAVA中利用JNI與VS2012實現C/C++的DLL調用