jni NewDirectByteBuffer for java.nio.IntBuffer(NewDirectIntBuffer)

时间:2016-02-15 18:54:29

标签: java android java-native-interface nio

如何为java.nio.IntBuffer制作NewDirectByteBuffer?又如何使用NewDirectIntBuffer?

这样可行:

    jclass canvasClass = env->GetObjectClass(obj);
    // in java:      public ByteBuffer command_ids_byte;
    fid_command_id = env->GetFieldID(canvasClass,"command_ids_byte","Ljava/nio/ByteBuffer;");

    jobject new_command_id_buffer = env->NewDirectByteBuffer(command_id.data(), command_id.size()*sizeof(int));
    env->SetObjectField(obj, fid_command_id, new_command_id_buffer);

虽然这不是(app崩溃):

    jclass canvasClass = env->GetObjectClass(obj);
    // in java:      public IntBuffer command_ids;
    fid_command_id = env->GetFieldID(canvasClass,"command_ids","Ljava/nio/IntBuffer;");

    // I'd want to have NewDirectIntBuffer here
    jobject new_command_id_buffer = env->NewDirectByteBuffer(command_id.data(), command_id.size()*sizeof(int));
    env->SetObjectField(obj, fid_command_id, new_command_id_buffer);

2 个答案:

答案 0 :(得分:0)

您可以从JNI调用Java asIntBuffer方法返回IntBuffer。要做到这一点,你需要获取ByteBuffer类,查找asIntBuffer方法,然后调用它。

jclass canvasClass = env->GetObjectClass(obj);
// in java:      public IntBuffer command_ids;
fid_command_id = env->GetFieldID(canvasClass,"command_ids","Ljava/nio/IntBuffer;");

// create ByteBuffer
jobject new_command_id_byte_buffer = env->NewDirectByteBuffer(command_id.data(), command_id.size()*sizeof(int));

// get ByteBuffer class
jclass bbclass = env->GetObjectClass(new_command_id_byte_buffer);
// look up asIntBuffer method from ByteBuffer class:
jmethodID asIntBuffer = env->GetMethodID(bbclass, "asIntBuffer", "()Ljava/nio/IntBuffer;");

// convert to IntBuffer:
jobject new_command_id_buffer = env->CallObjectMethod(new_command_id_byte_buffer, asIntBuffer);

env->SetObjectField(obj, fid_command_id, new_command_id_buffer);

答案 1 :(得分:0)

std::vector<jfloat> rect_x1;

// call with endian = ByteOrder.nativeOrder() from Java    
void flush(JNIEnv* env, jobject obj, jobject endian){
  jclass canvasClass = env->GetObjectClass(obj);

  jclass ByteBufferClass = env->FindClass("java/nio/ByteBuffer");
  jclass FloatBufferClass = env->FindClass("java/nio/FloatBuffer");
  jmethodID asFloatBuffer_methodID = env->GetMethodID(ByteBufferClass, "asFloatBuffer", "()Ljava/nio/FloatBuffer;");

  jmethodID order_methodID = env->GetMethodID(ByteBufferClass, "order", "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");

      {
          jfieldID fid = env->GetFieldID(canvasClass, "drawRect_x1",
                                         "Ljava/nio/FloatBuffer;");
          jobject new_buffer = env->NewDirectByteBuffer(rect_x1.data(),
                                                        rect_x1.size() * sizeof(jfloat));
          env->CallObjectMethod(new_buffer, order_methodID, endian);
          jobject new_buffer_float = env->CallObjectMethod(new_buffer,
                                                           asFloatBuffer_methodID);
          env->SetObjectField(obj, fid, new_buffer_float);
        }
}