Android JNI从Java类中获取Two Fields
在我发布任何代码或任何内容之前,让我解释一下我要完成的任务:我要做的是从资源文件夹获取加载着色器,并将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 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
)。