简体   繁体   English

Android JNI从Java类中获取Two Fields

[英]Android JNI get Two Fields from Java class

Before I post any code or anything, let me explain what I'm trying to accomplish: what I'm trying to do is get load shaders from an assets folder, and pass an array of PongDroidShader objects to C++ so it can compile and load them. 在我发布任何代码或任何内容之前,让我解释一下我要完成的任务:我要做的是从资源文件夹中获取加载着色器,并将PongDroidShader对象数组传递给C ++,以便它可以编译和加载他们。

In my Java class, I have a function which goes through each shader file in the shaders folder and parses it loads it into a String object, while also checking for what kind of shader type it is via its file extension (.eg, a vertex would have a .vert extension). 在我的Java类中,我有一个函数,它遍历着色器文件夹中的每个着色器文件并解析它将它加载到String对象中,同时还通过其文件扩展名检查它是什么类型的着色器类型(.eg,一个顶点)会有.vert扩展名)。 Once I've accomplished that, I then send it to my native compileShaders function, which takes the array of PongDroidShader objects, and the size of the array. 一旦我完成了,我就把它发送到我的本机compileShaders函数,它接受PongDroidShader对象的数组和数组的大小。

After that, I parse and link the shaders from the JNI code. 之后,我解析并链接JNI代码中的着色器。

So far, I'm having trouble getting the JNI to recognize the Java code and load it into variables. 到目前为止,我无法让JNI识别Java代码并将其加载到变量中。 What I have so far is as follows: 我到目前为止的内容如下:

Java Code Java代码

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

private class ShaderHandler {


        ...

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

        ...

JNI/C++ Code 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;
    }

}

I've omitted a lot of what exists in the code base just for the sake of simplicity. 为简单起见,我省略了代码库中存在的很多内容。 Note that even though compileShaders isn't shown being called, it is called by the activity class which wraps its parent class as an inner private class. 请注意,即使未显示compileShaders被调用,它也会被activity类调用,该类将其父类包装为内部私有类。

So far, my log output is as follows: 到目前为止,我的日志输出如下:

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)

I believe you should be using this to get your fields: 我相信你应该用这个来获得你的领域:

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

And move the class & field getting out of the loop. 并将类和字段移出循环。

EDIT: Also this: 编辑:也是这样的:

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

to get String value from mShaderSrc is wrong. 从mShaderSrc获取String值是错误的。

You should be using: 你应该使用:

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;" );

I solved the problem: Eclipse wasn't recognizing my classpath. 我解决了这个问题:Eclipse没有识别出我的类路径。 If anyone is having similar issues, then they need to go to Window->Preferences->Java->Build Paths->Classpath, and add the classpath to the Android SDK platform they are using, as well as the path to their project's class root (eg $PROJECT_ROOT/bin/classes ). 如果有人遇到类似问题,那么他们需要转到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