java — JNI: прямое чтение буфера & amp; пишу

У меня есть небольшой метод JNI, чтобы получить пиксель с экрана. Метод получает ByteBuffer из Java и записывается в C ++ в соответствии с этим вопросом. как писать и читать из байтового буфера передачи из Java в JNI.

Хотя это работает, я заметил, что первый байт, который я пишу, неверен, но остальные:

Длина ввода 3 в начале 000000000239F238

Цвет 202, 97, 79

значения, прочитанные в 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")

Почему первый байт неверен? Я предполагаю, что это имеет отношение к его знаку? Но опять же, почему другие не ошибаются? Я не уверен, почему это происходит.

2

Решение

Как отметил Ричард в комментариях, это связано со знаком байта. Это совпадение, что два других значения являются правильными, потому что они не идут выше 127; RGB не имеет знака и находится в диапазоне от 0 до 255, а байт со знаком — от -128 до 127.

Байты правильны в буфере, но Java buffer.get() читает это подписано.

Чтобы решить эту проблему, позвоните Byte.toUnsignedInt (…) (Java API) с прочитанным байтом.

Кроме того, вы можете создать метод расширения в Kotlin:

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

который вы можете использовать для вызова get () в буфере следующим образом:

val r = buffer.get().toUnsigned()
val g = buffer.get().toUnsigned()
val b = buffer.get().toUnsigned()
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]