我目前正在为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));
}
};
}