Android的JNI获得Java类两个领域 [英] Android JNI get Two Fields from Java class

查看:186
本文介绍了Android的JNI获得Java类两个领域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我张贴任何code或什么的,让我解释什么,我试图完成:
我想要做的就是从资产文件夹负载着色器,并通过 PongDroidShader 对象的数组到C ++,因此它可以编译并加载它们。

在我的Java类中,我有经历的着色器文件夹中的每个着色器文件,并解析其加载到一个字符串对象的功能,同时还检查什么一种着色类型是通过其文件扩展名(继,例如一个顶点将有一个 .vert 扩展名)。一旦我做到了这一点,我然后将其发送到我的家乡 compileShaders 函数,该函数 PongDroidShader 对象的数组和尺寸的阵列

在这之后,我分析,并从JNI code链接的着色器。

到目前为止,我遇到麻烦JNI认识到Java的code并将其加载到变量。我至今如下:

的Java code

 公共final类PongDroidShader {
    公共字符串mShaderSrc;
    公共ShaderType MTYPE;
}私有类ShaderHandler {
        ...        私人本地无效compileShaders(PongDroidShader []着色器,INT shaderCount);        ...

JNI / C ++ code

  JNIEXPORT无效JNICALL Java_com_grepwise_pongdroid_PongDroid_00024ShaderHandler_compileShaders
  (JNIEnv的* ENV,jobject OBJ,jobjectArray着色器,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场= env-> GetFieldID(clazz中,M型,ShaderType);        jobject着色器= env-> GetObjectArrayElement(着色器,I);        常量jchar jShaderChr = env-> GetCharField(着色器,env-> GetFieldID(clazz中,mShaderSrc,爪哇/郎/字符串));        的jstring jShaderStr = env-> NewString(安培; jShaderChr,sizeof的(jShaderChr));        为const char * shaderStr = env-> GetStringUTFChars(jShaderStr,0);        // TODO实现GL着色器操作和分配这里        ::的Optim配置::登录::信息(测试着色器:%S,shaderStr);        删除shaderStr;
    }}

我省略了很多在code碱基存在什么只是为了简单起见。请注意,即使 compileShaders 不显示被调用,它的的由包裹它的父类作为一个内部私有类的活动类调用。

到目前为止,我的日志输出如下:

  04-25 22:20:​​56.267 11985 11985ðdalvikvm:试图加载的lib /data/data/com.grepwise.pongdroid/lib/libnativepd.so 0x4051c800
04-25 22:20:​​56.275 11985 11985ðdalvikvm:增加了共享库/data/data/com.grepwise.pongdroid/lib/libnativepd.so 0x4051c800
04-25 22:20:​​56.322 11985 11985ðdalvikvm:GetFieldID:无法找到现场LCOM / grepwise / pongdroid / PongDroidShader; .mType:ShaderType
04-25 22:20:​​56.322 11985 11985ðdalvikvm:GetFieldID:无法找到现场LCOM / grepwise / pongdroid / PongDroidShader; .mShaderSrc:JAVA / LANG /字符串
04-25 22:20:​​56.330 11985 11985我dalvikvm:在com.grepwise.pongdroid.PongDroid $ ShaderHandler.compileShaders(本机方法)
04-25 22:20:​​56.330 11985 11985我dalvikvm:在com.grepwise.pongdroid.PongDroid $ ShaderHandler.access $ 1(PongDroid.java:128)
04-25 22:20:​​56.330 11985 11985我dalvikvm:在com.grepwise.pongdroid.PongDroid.onCreate(PongDroid.java:72)


解决方案

我相信你应该用它来得到你的字段:

  env-> GetFieldID(clazz中,M型,LCOM / grepwise / pongdroid / ShaderType;);
env-> GetFieldID(clazz中,mShaderSrc,Ljava /朗/字符串;)

和移动类和放大器;场走出循环。

编辑:
另外这款:

 常量jchar jShaderChr = env-> GetCharField(...)

获取字符串值从mShaderSrc是错误的。

您应该使用:

 的jstring jShaderStr =(的jstring)env-> GetObjectField(...);
为const char * shaderSrc = env-> GetStringUTFChars(jShaderStr,0);
// ...在这里使用shaderSrc
env-> ReleaseStringUTFChars(hShaderStr,shaderSrc);

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.

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 (.e.g, a vertex would have a .vert extension). 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.

After that, I parse and link the shaders from the JNI code.

So far, I'm having trouble getting the JNI to recognize the Java code and load it into variables. What I have so far is as follows:

Java Code

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

private class ShaderHandler {


        ...

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

        ...

JNI/C++ Code

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.

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.

You should be using:

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

这篇关于Android的JNI获得Java类两个领域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆