隨筆-17  評論-6  文章-1  trackbacks-0
          HP-UX下使用JNI訪問標準C++程序

          問題的關鍵在于用aCC編譯時的參數
          根據HP網站上的兩篇文章可以很容易的使用JNI訪問傳統C++(Classical C++)程序
          http://www.hp.com/products1/unix/java/infolibrary/prog_guide/JNI_java2.html 
          http://forums1.itrc.hp.com/service/forums/questionanswer.do?admit=716493758+1092296929165+28353475&threadId=245738 
          但是,如果代碼中使用到了標準C++,也就是用到了STL,就會出現莫名其妙的JVM crash. 而且一般的現象是使用string的時候出錯

          最后發現是JVM的多線程機制和aCC編譯的缺省的多線程機制不一樣.所以編譯時需要加參數指定
          總的說來,編譯參數為
          OPTS=-AA +z +u4 -D_RWSTD_MULTI_THREAD -D_REENTRANT -D_HPUX -D_HPUX_SOURCE -D_POSIX_C_SOURCE=199506L -D_XOPEN_SOURCE_EXTENDED 

          其中,-D_RWSTD_MULTI_THREAD -D_REENTRANT 是指定多線程機制;同時必須添加-D_HPUX_SOURCE 參數,否則,編譯時會出現奇怪的錯誤
          連接參數為
          -AA -b -lCsup_v2 -lstd_v2 
          值得注意的是根據上面所說的第二篇文章可知使用-AA編譯連接時,要連的庫是libCsup_v2.sllibstd_v2.sl(這兩個庫是支持標準C++的庫),而不是第一篇文章中提到的libCsup.sllibstd.sl(這兩個庫是支持傳統C++的庫). 

          另外,有幾個碰到的問題
          1. 
          如果編譯參數沒有指定多線程機制,禁用JIT(啟動JVM加參數:-Djava.compiler=none -Xint )可以使簡單的例子通過,但是有些情況下還是會出錯

          2. 
          null作為String傳入JNI native接口代碼中是,使用env->GetStringUTFChars(jstring)會出現如下錯誤導致虛擬機崩潰
          Function=verify_instance_jfieldID__18jfieldIDWorkaroundSFP12klassOopDescP9_jfieldID 

          3. 
          在使用String作為JNI的傳入傳出參數,使用GetStringUTFChars解決不了中文問題,還是會有亂碼正確的解決方法是使用以下兩個函數
          void JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg) 

              jclass cls = env->FindClass(name); 
              /* if cls is NULL, an exception has already been thrown */ 
              if (cls != NULL) { 
                  env->ThrowNew(cls, msg); 
              } 
              /* free the local ref */ 
              env->DeleteLocalRef(cls); 


          jstring JNU_NewStringNative(JNIEnv *env, const char *str) 

            if (str==NULL) 
            { 
             return NULL; 
            } 
            jclass jcls_str = env->FindClass("java/lang/String"); 
            jmethodID jmethod_str = env->GetMethodID(jcls_str, "", "([B)V"); 

            jstring result; 
            jbyteArray bytes = 0; 
            int len; 

            if (env->EnsureLocalCapacity(2) < 0) { 
              return NULL; /* out of memory error */ 
            } 
            len = strlen(str); 
            bytes = env->NewByteArray(len); 
            if (bytes != NULL) { 
              env->SetByteArrayRegion(bytes, 0, len,(jbyte *)str); 
              result = (jstring)env->NewObject(jcls_str, jmethod_str, bytes); 
              env->DeleteLocalRef(bytes); 
              return result; 
            } /* else fall through */ 
            return NULL; 



          char *JNU_GetStringNativeChars(JNIEnv *env, jstring jstr) 

              jbyteArray bytes = 0; 
              jthrowable exc; 
              char *result = 0; 
              if (env->EnsureLocalCapacity(2) < 0) { 
                  return 0; /* out of memory error */ 
              } 
          jclass jcls_str = env->FindClass("java/lang/String"); 
          jmethodID MID_String_getBytes = env->GetMethodID(jcls_str, "getBytes", "()[B"]; 

              bytes = (jbyteArray)env->CallObjectMethod(jstr, MID_String_getBytes); 
              exc = env->ExceptionOccurred(); 
              if (!exc) { 
                  jint len = env->GetArrayLength( bytes); 
                  result = (char *)malloc(len + 1); 
                  if (result == 0) { 
                      JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 
                                      0); 
                      env->DeleteLocalRef(bytes); 
                      return 0; 
                  } 
                  env->GetByteArrayRegion(bytes, 0, len, (jbyte *)result); 
                  result[len] = 0; /* NULL-terminate */ 
              } else { 
                  env->DeleteLocalRef(exc); 
              } 
              env->DeleteLocalRef(bytes); 
              return (char*)result; 


          ★注意:使用char *JNU_GetStringNativeChars()獲得的指針用完后要顯式的free().

          posted on 2006-02-27 15:54 小鐵匠 閱讀(982) 評論(0)  編輯  收藏 所屬分類: java


          My blog is worth $10,000,000.00 ^_^.
          How much is your blog worth?

          <2006年2月>
          2930311234
          567891011
          12131415161718
          19202122232425
          2627281234
          567891011

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          相冊

          搜索

          •  

          積分與排名

          • 積分 - 58783
          • 排名 - 887

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 南乐县| 石首市| 逊克县| 荃湾区| 黔西县| 长宁区| 锡林郭勒盟| 肥城市| 中牟县| 江达县| 呼和浩特市| 贵州省| 个旧市| 昌都县| 永昌县| 雅安市| 罗甸县| 江津市| 湖口县| 磴口县| 布尔津县| 富蕴县| 禄劝| 河源市| 鄂尔多斯市| 拜城县| 曲阜市| 吕梁市| 通江县| 库伦旗| 衡阳县| 河东区| 奉新县| 犍为县| 临城县| 铁力市| 安徽省| 陕西省| 延安市| 刚察县| 新宾|