簡體   English   中英

Android JNI從Java類中獲取Two Fields

[英]Android JNI get Two Fields from Java class

在我發布任何代碼或任何內容之前,讓我解釋一下我要完成的任務:我要做的是從資源文件夾中獲取加載着色器,並將PongDroidShader對象數組傳遞給C ++,以便它可以編譯和加載他們。

在我的Java類中,我有一個函數,它遍歷着色器文件夾中的每個着色器文件並解析它將它加載到String對象中,同時還通過其文件擴展名檢查它是什么類型的着色器類型(.eg,一個頂點)會有.vert擴展名)。 一旦我完成了,我就把它發送到我的本機compileShaders函數,它接受PongDroidShader對象的數組和數組的大小。

之后,我解析並鏈接JNI代碼中的着色器。

到目前為止,我無法讓JNI識別Java代碼並將其加載到變量中。 我到目前為止的內容如下:

Java代碼

public final class PongDroidShader {
    public String mShaderSrc;
    public ShaderType mType;
}

private class ShaderHandler {


        ...

        private native void compileShaders(PongDroidShader[] shaders, int shaderCount);

        ...

JNI / C ++代碼

JNIEXPORT void JNICALL Java_com_grepwise_pongdroid_PongDroid_00024ShaderHandler_compileShaders
  (JNIEnv * env, jobject obj, jobjectArray shaders, jint sizeOfShaders) {

    for( int i = 0; i < sizeOfShaders; ++i )
    {
        jclass clazz = env->FindClass( "com/grepwise/pongdroid/PongDroidShader" );
        jclass shaderTypeEnum = env->FindClass( "com/grepwise/pongdroid/ShaderType" );

        jfieldID field = env->GetFieldID( clazz, "mType", "ShaderType" );

        jobject shader = env->GetObjectArrayElement( shaders, i );

        const jchar jShaderChr = env->GetCharField( shader, env->GetFieldID( clazz, "mShaderSrc", "java/lang/String" ) );

        jstring jShaderStr = env->NewString( &jShaderChr, sizeof( jShaderChr ) );

        const char* shaderStr = env->GetStringUTFChars( jShaderStr, 0 );

        //TODO implement GL Shader Manipulation and Allocation here

        optim::Config::Log::info( "Testing shader: %s", shaderStr );

        delete shaderStr;
    }

}

為簡單起見,我省略了代碼庫中存在的很多內容。 請注意,即使未顯示compileShaders被調用,它也會被activity類調用,該類將其父類包裝為內部私有類。

到目前為止,我的日志輸出如下:

04-25 22:20:56.267 11985 11985 D dalvikvm: Trying to load lib /data/data/com.grepwise.pongdroid/lib/libnativepd.so 0x4051c800
04-25 22:20:56.275 11985 11985 D dalvikvm: Added shared lib /data/data/com.grepwise.pongdroid/lib/libnativepd.so 0x4051c800
04-25 22:20:56.322 11985 11985 D dalvikvm: GetFieldID: unable to find field Lcom/grepwise/pongdroid/PongDroidShader;.mType:ShaderType
04-25 22:20:56.322 11985 11985 D dalvikvm: GetFieldID: unable to find field Lcom/grepwise/pongdroid/PongDroidShader;.mShaderSrc:java/lang/String
04-25 22:20:56.330 11985 11985 I dalvikvm:   at com.grepwise.pongdroid.PongDroid$ShaderHandler.compileShaders(Native Method)
04-25 22:20:56.330 11985 11985 I dalvikvm:   at com.grepwise.pongdroid.PongDroid$ShaderHandler.access$1(PongDroid.java:128)
04-25 22:20:56.330 11985 11985 I dalvikvm:   at com.grepwise.pongdroid.PongDroid.onCreate(PongDroid.java:72)

我相信你應該用這個來獲得你的領域:

env->GetFieldID( clazz, "mType", "Lcom/grepwise/pongdroid/ShaderType;" );
env->GetFieldID( clazz, "mShaderSrc", "Ljava/lang/String;" )

並將類和字段移出循環。

編輯:也是這樣的:

const jchar jShaderChr = env->GetCharField(...)

從mShaderSrc獲取String值是錯誤的。

你應該使用:

jstring jShaderStr = (jstring)env->GetObjectField(...);
const char* shaderSrc = env->GetStringUTFChars(jShaderStr, 0);
// ... here use shaderSrc
env->ReleaseStringUTFChars(hShaderStr, shaderSrc);

您必須從實例獲取私有字段,並將簽名作為第三個參數傳遞。

jfieldID field = env->GetFieldID( obj, "mShaderSrc", "Ljava/lang/String;" );

我解決了這個問題:Eclipse沒有識別出我的類路徑。 如果有人遇到類似問題,那么他們需要轉到Window-> Preferences-> Java-> Build Paths-> Classpath,並將類路徑添加到他們正在使用的Android SDK平台,以及他們項目類的路徑root(例如$PROJECT_ROOT/bin/classes )。

暫無
暫無

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

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