2008年6月13日 星期五

[Java] 如何把 C++ 的 LONGLONG 轉成 Java 的 BigInteger

有時候 Java 只是作為一個介面的外殼, 高效率的演算法最後還是要用 C++ 來運算, 然後把東西吐出來給介面端使用. 那麼問題是怎麼把 C++ 底層運算的大數結果, 回傳給 Java 呢?

例如
要把 LONGLONG bigInteger=12345678910111213L 轉成 BigInteger.

要怎麼做?


我的作法是:  將 LONGLONG 轉成 byte array 的方式傳回去, 然後利用 BigInteger 建構子建立對應的大整數.

 

詳細程式碼如下:

如何把 C++ 的 LONGLONG 轉成 Java 的 BigInteger


// 如何把 C++ 的 LONGLONG 轉成 Java 的 BigInteger
// 井民全
public static void getTotalBytes(){
byte[] retBytes=new byte[8];

// 呼叫 JNI 取得 C++ 底層計算的大數 (用 bytes 陣列表示)
getTotalBytes(retBytes);

// 組合成 BigInteger
BigInteger totalbytes=new BigInteger(retBytes);

for(int i=0;i < retBytes.length;i++){
System.out.println("retBytes["+i+"]="+retBytes[i]);
}
System.out.println("totalbytes="+totalbytes);

}

 


JNI 的轉換程式部分



// JNI 的轉換程式部分
// 行為:
// 假設我們要把 LONGLONG bigInteger=12345678910111213L 轉成 BigInteger.
// 作法:
// 將 LONGLONG 轉成 byte array 的方式傳回去, 然後利用 BigInteger 建構子建立對應的大整數
JNIEXPORT void JNICALL Java_Manager_CameraManager_getTotalBytes(JNIEnv *env, jclass obj, jbyteArray jbyteArray){
// 測試的 LONGLONG
LONGLONG bigInteger=12345678910111213L;

// 取出陣列內容
jbyte* byteArray=env->GetByteArrayElements(jbyteArray,JNI_FALSE);
int length=env->GetArrayLength(jbyteArray);

// 最小值從高位址開始放 (Big-endian)
char* buf=(char*)&bigInteger;
int c=0;
for(int i=length-1;i >= 0;i--,c++){
if(c < sizeof(bigInteger))
byteArray[i]=*(buf+c);
else
byteArray[i]=0;
}

// 把資料 update 回 java
env->ReleaseByteArrayElements(jbyteArray,byteArray,0);
}


by Jing

3 則留言:

  1. 井先生你好~
    真不好意思~
    想和你請教和這篇文章沒有關係的問題
    就是你要秀的"程式碼"是如何嵌入到你的blog裡的?
    有網站提供這樣的服務嗎?謝謝~
    謝謝~

    回覆刪除
  2. 顯示程式確實麻煩的很,
    你可以參考我過去寫的文章
    [程式設計] 顯示程式碼--SyntaxHighlighter
    網址: http://mqjing.blogspot.com/2008/02/syntaxhighlighter.html
    裡面有詳細步驟.

    回覆刪除