java - Android JNI 从 Java 类中获取两个字段

标签 java android c++ android-ndk

在我发布任何代码或任何内容之前,让我解释一下我要完成的工作: 我想要做的是从 Assets 文件夹中获取加载着色器,并将一组 PongDroidShader 对象传递给 C++,以便它可以编译和加载它们。

在我的 Java 类中,我有一个函数遍历 shaders 文件夹中的每个着色器文件并将其解析加载到 String 对象中,同时还检查它是哪种着色器类型通过其文件扩展名(例如,顶点将具有 .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,它也 由将其父类包装为内部私有(private)类的 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 获取字符串值是错误的。

你应该使用:

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

关于java - Android JNI 从 Java 类中获取两个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10327773/

相关文章:

java - 如何检查两个单词是否是字谜

java - 使用数组实现我自己的 ArrayList

java - 比较java中的两个整数字符串

java - 处理应用程序上下文

c++ - 使用 libconfig 导入数组或列表设置

c++ - CONFIGRET 返回类型是什么意思?

java - 如何跳过格式正确性检查 XML

android形状不改变大小

java - 在 Gridview 中更新图像时出现问题

c++ - 整数递增使应用程序崩溃