2013-02-28 32 views
5

ここでは本当に大きな問題があります。私はJavaからC++にbyte []を渡そうとしており、変換後に負の値を取得しています。私はJavaバイト[]に変換してログをとった後に値が0または負であるというユニークな文字を持つ問題を解決しました。JNI Java byte []をC++ bytearrayに変換して返す0

文字列のテストバイト[]を使用しようとしましたが正常に動作します。

ここに私のコードがあります。

のJava

public static native void SendMessage(byte[] message, int size); //size = message.length 

C++

static void SendMessage(JNIEnv *env, jclass cls, jbyteArray array, jint array_length) 
{ 
    jbyte* content_array = (env)->GetByteArrayElements(array,NULL); 
    //*env->GetByteArrayRegion(array,0,array_length,content_array); //tried this as well, same results 
    LOGD("content:\n"); 
    for (int i=0; i < array_length; i++) 
    { 
     LOGD("%d",content_array[i]); 
    } 

    //EDIT 
    SendMessage(client, (uint8_t*)content_array, array_length); //<- could the problem be at the point where I convert it to uint8_t? 

     (env)->ReleaseByteArrayElements(array,content_array,0); 
    } 

content: 48 
content: 23 
content: 13 
content: 56 
content: 0 // <--- the problem starts here 
content: -122 
content: 0 
content: 78 
content: 32 
content: -28 
etc... 
.. 
.. 

出力、簡単なテストバイト[] のJava

String test = "ABC"; 
byte[] message = test.getBytes(); 
public static native void SendMessage(byte[] message, int size); //size = message.length 
0を使用してあなたの助けのための

C++

static void SendMessage(JNIEnv *env, jclass cls, jbyteArray array, jint array_length) 
{ 
    jbyte* content_array = (env)->GetByteArrayElements(array,NULL); 
    //*env->GetByteArrayRegion(array,0,array_length,content_array); //tried this as well, same results 
    LOGD("content:\n"); 
    for (int i=0; i < array_length; i++) 
    { 
     LOGD("%d",content_array[i]); 
     } 
     (env)->ReleaseByteArrayElements(array,content_array,0); 
    } 

出力

content: 65 //this works perfectly 
content: 66 
content: 67 

感謝。とても有難い。

答えて

1

問題の場合、byte[]アレイはどうやって入手していますか?それもStringからの変換ですか?そうであれば、ログ出力でゼロと負の値を得ることは完全に有効かもしれません。これは、入力文字と、バイト配列に変換するために使用しているエンコーディングに依存します。 String.getBytes()をシンプルテキストと同じように使用している場合は、プラットフォームのデフォルトエンコードを使用します。単純なケースでは、デフォルトのエンコーディングはASCII互換のものであることがわかります。

+0

返信いただきありがとうございます。いいえ、私は文字列変換からバイト[]を取得していません。バイト[]は別のソースから渡されます。私はそれをJava側で文字列に変換してログを記録し、ユニークな文字が含まれていることがわかりました。 異なるエンコーディングについて述べました。プラットフォームのデフォルトから別のエンコーディングを設定する方法は? – user2117849

+0

[String.getBytes(Charset)](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#getBytes(java.nio.charset.Charset))を使用します。 –

1

ここに問題があるとは思っていません。 Javaでは、byteは符号付きタイプなので、負の値は予期しないものではありません。 Jbyteは、おそらく8ビットの署名付きC++型にマッチします。

最も可能性の高い説明は以下のとおりです。

  • これは、あなたがバイト配列を作成している方法のいくつかのアーチファクトです。例えばそれは大きい何らかの理由

    • :あなたは

    • は間違っsizeパラメータの値を得ている(...ゼロはそう指示する傾向があるが)UTF-8でエンコードされていますバイト配列サイズより大きい。

    • バイト配列にstuffを書き込んだプロセスでは、sizeバイトが入りませんでした。


それはあなたのJNIコードが0 <= size < message.lengthいることを確認していないことは注目に値します。範囲外のsize引数を使用してこのメ​​ソッドを呼び出すと、ハード・JVMクラッシュにつながるセグメンテーション・フォルトを含む悪いことが起こる可能性があります。

+0

Stephenに感謝します。いいえ、サイズが正しいことを確認しました。しかし、私は自分の投稿で(編集後)、変換された配列をuint8_tにキャストしたとは言及していませんでした。受信側がメッセージが0になるまで読むことができるのはなぜですか? uint8_tは0と負の値をサポートしていますか? – user2117849

+0

'uint8_t'の値の範囲は0から255です。しかし、これはC/C++のキャストであるため、配列の値をunsignedとして扱うようにコードを指示しています。とにかく、アップデートに基づいて、あなたが私たちに示したコードに問題があるとは思わない。 –

関連する問題