2017-05-26 11 views
2

私は画面からピクセルを取得する小さなJNIメソッドを持っています。このメソッドは、JavaからByteBufferを受け取り、この質問how to write and read from bytebuffer passing from java to jniに従ってC++に書き込まれます。JNI:直接バッファの読み込みと書き込み

これは仕事をしている間、私は私が書く最初のバイトが正しくありませんが、他の人がしている気づい:

入力の長さが開始000000000239F238

色は202、97、79

あるで3ある

Javaで読む

値:-54、97、79

私のプログラムの出力です。

C++コード:

JNIEXPORT void JNICALL Java_capturePixel(JNIEnv * env, jobject clz, jobject buffer) 
{ 
    jbyte* bufferStart = static_cast<jbyte*>(env->GetDirectBufferAddress(buffer)); 
    jlong inputLength = env->GetDirectBufferCapacity(buffer); 


    HDC hScreenDC = GetDC(nullptr); 

    std::cout << "Input length is " << inputLength << " at start " << &bufferStart << std::endl; 

    COLORREF pixel = GetPixel(hScreenDC, 100, 20); 

    int r = GetRValue(pixel); 
    int g = GetGValue(pixel); 
    int b = GetBValue(pixel); 

    std::cout << "Color is " << r << ", " << g << ", " << b << std::endl; 

    bufferStart[0] = r; 
    bufferStart[1] = g; 
    bufferStart[2] = b; 
} 

私のJavaコード(実際にはKotlin):

val r = buffer.get() 
val g = buffer.get() 
val b = buffer.get() 
println("values read in java: $r, $g, $b") 

なぜ最初のバイトが間違っていますか?私はそれがその標識と関係していると仮定していますか?しかし、もう一度、なぜ他人は間違っていないのですか?なぜこれが起こっているのか分かりません。

+0

2Sは202 ==を補完:あなたは、このようなバッファ上のget()を呼び出すために使用することができます

fun Byte.toUnsigned(): Int = this.toInt() and 0xff 

また、あなたはKotlinで拡張メソッドを作成することができます-54。 Javaが符号付きの値を出力しています。 –

+0

@RichardCrittenなぜ最初のバイトだけが発生するのか説明できますか? – Limnic

+1

他の値は、設定しているバイトの最上位ビットを設定しません。値<= 127が正として出力され、値> = 128が負として出力されます。配列の値は正しいですが、それは出力だけであなたを混乱させます。 –

答えて

2

上記のコメントのリチャードは、バイトの記号と関係があります。 127を超えないので、2つの他の値が正しいことは偶然です。 RGBは符号なしで0〜255の範囲にあり、符号付きバイトの範囲は-128〜127です。

バイトはバッファ内では正しいですが、Java buffer.get()は署名付きで読み込みます。

これを解決する方法は、バイトを読み取ってByte.toUnsignedInt(...)(Java API)を呼び出すことです。

val r = buffer.get().toUnsigned() 
val g = buffer.get().toUnsigned() 
val b = buffer.get().toUnsigned() 
関連する問題