在Java中反序列化从c++通过JNI传递的protobuf ByteArray

Deserializing a protobuf ByteArray in Java that was passed from C++ over JNI

本文关键字:protobuf ByteArray JNI 通过 Java 反序列化 c++      更新时间:2023-10-16

我有一个protobuffer消息,其字段填充了数据。我在c++中首先将此消息序列化为char*,然后将该char*的内容复制到jbyteArray。然后我将jbyteArray返回给我的java类,我想在其中对它进行反序列化,这样我就可以访问消息/类的各个字段。但我真的不知道怎么做。

这是我到目前为止的代码:

public String IMEI(){
    GetDeviceInfo nativeDeviceInfo = new GetDeviceInfo();
    byte[] ret = nativeDeviceInfo.getDeviceData();
    CellPhoneDevice.Builder device = CellPhoneDevice.newBuilder();

    try {
        device.mergeFrom(ret);
    } catch (InvalidProtocolBufferException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    if(!device.hasImeiNumber())
        return "imei empty";
    long imei = device.getImeiNumber();

    String str = String.valueOf(imei);
//      String str = new String(ret);   //see if ByteArray is even filled
    return str;
}

我已经检查了byteArray是否包含数据(见注释行),它是填充的,所以我猜我在解析byteArray时做错了什么。我搜索了很多网站/教程,但没有太多关于反序列化byteArrays,如果有,我无法复制它(方法未定义等东西)。

当我运行这段代码时,它执行没有任何错误,但是应该包含imei的字符串只包含"0",并且该方法返回"imei empty"字符串。

所以,是的…谁能告诉我,反序列化byteArray的方法是什么?

如果您在本机代码中加载Java数组并且在Java端没有获得数据(0),请检查以确保您正在调用Release-TYPE-ArrayElements()。下面是一个示例代码片段:

if ((function & FUNCTION_04) > 0 ) {
    arrayB = (jbyteArray) (*env)->GetObjectField(env, jObjectOut, fidB);
    pArrayB = (*env)->GetByteArrayElements(env, arrayB, 0);
    arrayBsize = (*env)->GetArrayLength(env, arrayB);
    for (x = 0; x < arrayBsize; x++) {
        pArrayB[x] = x;
    }
    (*env)->ReleaseByteArrayElements(env, arrayB, pArrayB, 0);
}

阅读:http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html