java - JNI : Direct buffer reading & writing

标签 java c++ java-native-interface kotlin

我有一个小的 JNI 方法来从屏幕上检索像素。该方法从Java接收一个ByteBuffer,并根据这个问题用C++写入how to write and read from bytebuffer passing from java to jni .

虽然这确实有效,但我注意到我写入的第一个字节不正确,但其他字节是:

Input length is 3 at start 000000000239F238

Color is 202, 97, 79

values read in 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()

关于java - JNI : Direct buffer reading & writing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44197468/

相关文章:

java - MSVC++ 只编译/禁用链接器

java DOM xml文件创建 - 输出文件中没有制表符或空格

java - 一个线程大部分时间都在运行

c++ - 我的 If Else 语句无法提供 vector 中的最大值 (C++)

c++ - Qt Creator 自动完成 : Enable mid-string matching

java - 安卓NDK : How to clean up native code after restarting activity?

java - 如何捕获 spring-integration 套接字服务器中的错误?

java - netty-如何一起传输消息和数据?

c++ - 如何从C函数访问C++类数据成员

java-native-interface - 加载共享库 : libjvm. 时出错,因此: