如何使用Djinni将图像从Java传递到C ++

时间:2019-05-27 19:50:03

标签: java android c++ opencv djinni

我目前正在为Android应用开发程序,其核心功能是用C ++编写的。我将Djinni用作C ++和Java(也包括C ++和Objective-C)之间的接口。由于它是图像处理应用程序,因此我也使用OpenCV。我想将手机摄像头拍摄的图像传递给C ++代码,并在那里进行OpenCV处理。

我使用this post尝试实现自定义数据类型byte_buffer,以便Java ByteBuffer可以转换为C ++ int8_t *。但是按照上述说明,我遇到了一个问题,那就是:在将ByteBuffer变量从Decoder.java传递到NativeDecoder.cpp时,我的ByteBuffer变量变为空。因此,在代码的C ++部分中,该值始终为NULL。

我在注释的代码中添加了调试时获得的值。 这是我第一次与Djinni和JNI一起工作,因此我可能不会注意到明显的问题,但是这里的其他类似问题并不能使我清楚我做错了什么。

我的coder.djinni(decoder.yaml与上述文章中描述的几乎相同):

   @extern "decoder.yaml"

   decoder =
   interface +c {
        static create(): decoder;
        decode(image: byte_buffer):string;
   }

我的Java代码:

Decoder decoder = Decoder.create();
ByteBuffer buffer = ByteBuffer.wrap(imageBytes);
String result = decoder.decode(buffer);

我生成的Decoder.java:

public abstract class Decoder {

    public abstract String decode(java.nio.ByteBuffer image);

    ...

    private static final class CppProxy extends Decoder
    {
        ...

        @Override
        public String decode(java.nio.ByteBuffer image)
        {
            assert !this.destroyed.get() : "trying to use a destroyed object";
            return native_decode(this.nativeRef, image); //here the image variable is okay (java.nio.HeapByteBuffer[pos=0 lim=241269 cap=241269])
        }
        private native String native_decode(long _nativeRef, java.nio.ByteBuffer image);
    }
}

我生成的NativeDecoder.cpp:

CJNIEXPORT jstring JNICALL Java_com_rmcode_scanner_Decoder_00024CppProxy_native_1decode(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, ::djinni::ByteBuffer::JniType j_image)
{
    try {
        DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef);
        const auto& ref = ::djinni::objectFromHandleAddress<::decoder::Decoder>(nativeRef);
        auto r = ref->decode(::djinni::ByteBuffer::toCpp(jniEnv, j_image));// here j_image is 0xbec4bd80
        return ::djinni::release(::djinni::String::fromCpp(jniEnv, r));
    } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}

我在传递过程中生成的用于类型转换的JNI代码:

namespace djinni {
    struct ByteBuffer {
        using CppType = int8_t *;
        using JniType = jobject;

        static CppType toCpp(JNIEnv* env, JniType j) {
            return (int8_t *) env->GetDirectBufferAddress(j);
        }

        static JniType fromCpp(JNIEnv *env, CppType c) {
            return env->NewDirectByteBuffer(c, sizeof(c));
        }
    };
}

0 个答案:

没有答案