簡體   English   中英

如何從 JNI 中的 C++ 返回復雜的 java class 實例?

[英]How to return a complex java class instance from C++ in JNI?

我需要在從 Java JNI 調用的 C++ 代碼中返回此 class 的自定義實例

public class DecodedFrame {
    public enum DecodedFrom{
        FFMPEG,
        MEDIA_CODEC
    }
    ByteBuffer[] buffer;
    DecodedFrom decodedFrom;
    PixelFormat pixelFormat;
    int[] linesize;
    int[] width;
    int[] height;
    int[] planeSize;
    int[] textureSize;
}

我發現https://stackoverflow.com/a/43364063/6655884給出了如何做的好主意。 它使用 class 構造函數,如下所示: jmethodID javaConstructor = env->GetMethodID(javaGlobalClass, "<init>", "(ZLjava/lang/String;)V"); . 我真的需要使用構造函數嗎? 我沒有使用一個,因為我想設置自定義數量的數組成員,例如linesizewidth等。

我知道如何創建 ByteBuffer 的實例:

jobject directBuffer = env->NewDirectByteBuffer(myBuffer, myBufferSize);

ByteBuffer 數組可以這樣定義,我認為:

jobjectArray ret= (jobjectArray)env->NewObjectArray(3,  
     env->FindClass("java/what????/ByteBuffer"),  
     env->whatHere???);  

for(i=0;i<3;i++) {  
    env->SetObjectArrayElement(  
    ret,i,NewDirectByteBuffer(myBuffer[i], myBufferSize[i]));  
}  

但是如何將buffer組件設置為值ret 如何設置linesize數組? 我不知道沒有構造函數怎么辦。

這是很多問題。 請查看JNI 手冊 這是一個很好的閱讀,一切都在那里解釋。

為了回答你的一些問題...

我真的需要使用構造函數嗎?

是的,但在 DecodedFrame 的情況下, DecodedFrame提供了一個默認幀。 如果您打算在本機代碼中實例化DecodedFrame ,您只需要引用它:

jclass decodedFrameClass = env->FindClass("my.package.DecodedFrame");
jmethodID decodedFrameConstructor = env->GetMethodID(decodedFrameClass, "<init>", "()V");
jobject decodedFrame = env->NewObject(decodedFrameClass, decodedFrameConstructor);

ByteBuffer 數組可以這樣定義,我認為:

 jobjectArray ret= (jobjectArray)env->NewObjectArray(3, env->FindClass("java/what????/ByteBuffer"), env->whatHere???);

嘗試

jobjectArray ret= (jobjectArray)env->NewObjectArray(3,  
     env->FindClass("java.nio.ByteBuffer"), NULL);  

...如何將buffer組件設置為值ret

要設置buffer屬性,您首先需要一個DecodedFrame的實例。

jfieldID bufferID = env->GetFieldID(decodedFrameClass, "buffer", "[Ljava/nio/ByteBuffer;");
env->SetObjectField(decodedFrame, bufferID, ret);

如何設置linesize數組?

jintArray arr = env->NewIntArray(10000);
jfieldID linesizeID = env->GetFieldID(decodedFrameClass, "linesize", "[I");
env->SetObjectField(decodedFrame, linesizeID, arr);

"[I"JNI Manual中也有解釋)

我不知道沒有構造函數怎么辦。

您可以在 Java 中構造一個實例並將該實例傳遞給本機代碼。 然后,您不需要在本機代碼中實例化 object。

DecodedFrame df = new DecodedFrame();
nativeCall(df);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM