У меня есть небольшой метод 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")
Почему первый байт неверен? Я предполагаю, что это имеет отношение к его знаку? Но опять же, почему другие не ошибаются? Я не уверен, почему это происходит.
Как отметил Ричард в комментариях, это связано со знаком байта. Это совпадение, что два других значения являются правильными, потому что они не идут выше 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()
Других решений пока нет …