jni数据和对象处理

来源:互联网 发布:js 调用id为变量的div 编辑:程序博客网 时间:2024/06/06 07:05
#include "Texture.h"#include "SampleUtils.h"#include <string.h>Texture::Texture() :mWidth(0),mHeight(0),mChannelCount(0),mData(0),mTextureID(0){}Texture::~Texture(){    if (mData != 0)        delete[]mData;}/** * JNIEnv自变量——它是指向类型为JNIEnv_的一个特殊JNI数据结构的指针。利用它程序员可以访问一系列函数,如 * 获取版本信息、进行类和对象操作、控制对Java对象的全局和局部引用、访问实例字段和静态字段、 * 调用实例方法和静态方法、执行字串和数组操作、产生和控制Java异常等。 * jobject自变量——对于非static方法(也叫作实例方法),它等价于C++的“this”指针,并类似于Java的“this”:都引用了调用固有方法的那 个对象。 * 对于static方法,它是对特定Class对象的一个引用,方法就是在那个Class对象里实现的。本例在头文件中声明的方法就是静态方法,因此表示对Texture * 对象的一个引用 */Texture*Texture::create(JNIEnv* env, jobject textureObject){    Texture* newTexture = new Texture();    // Handle to the Texture class:    /**     * 简单介绍一下FindClass和GetObjectClass的区别:     * FindClass是通过传java中完整的类名来查找java的class,     * 而GetObjectClass是通过传入jni中的一个java的引用来获取该引用的类型。     * 前者要求你必须知道完整的类名,后者要求在Jni有一个类的引用。     * 例如:jclass cls = env->FindClass("com/ldq/Student");注意这里不能是com.ldq.Student     * 本例中textureObject是类Texture对象的一个引用,因此可以使用GetObjectClass     * textureClass可认为是类的一个句柄     */    jclass textureClass = env->GetObjectClass(textureObject);    // Get width:    /**     * 获得实例对象的成员变量的ID     * 第一个参数是类句柄,第二个参数是变量名称,第三个参数是变量属性(注:对象的属性对比见表1)     * I 表示int     * 下面的类似     */    jfieldID widthID = env->GetFieldID(textureClass, "mWidth", "I");    if (!widthID)    {        LOG("Field mWidth not found.");        return 0;    }    /**     * 操作成员变量,根据ID获取value,并赋值     */    newTexture->mWidth = env->GetIntField(textureObject, widthID);    // Get height:    /**     * 这个和上面一样     */    jfieldID heightID = env->GetFieldID(textureClass, "mHeight", "I");    if (!heightID)    {        LOG("Field mHeight not found.");        return 0;    }    newTexture->mHeight = env->GetIntField(textureObject, heightID);    // Always use RGBA channels:    newTexture->mChannelCount = 4;    // Get data:    /**     * 获得一个实例对象方法的ID     * ()[B 表示返回的是byte[]     * 第一个参数是类句柄,第二个参数是方法名称,第三个参数是变量属性(注:对象的属性对比见表1)     */    jmethodID texBufferMethodId = env->GetMethodID(textureClass , "getData", "()[B");    if (!texBufferMethodId)    {        LOG("Function GetTextureBuffer() not found.");        return 0;    }    /**     * 调用方法,将返回的数值保存     */    jbyteArray pixelBuffer = (jbyteArray)env->CallObjectMethod(textureObject, texBufferMethodId);        if (pixelBuffer == NULL)    {        LOG("Get image buffer returned zero pointer");        return 0;    }    jboolean isCopy;    /**     * JNI数组存取函数见表2     * GetXXXArrayElements XXX代表数组的类型     */    jbyte* pixels = env->GetByteArrayElements(pixelBuffer, &isCopy);    if (pixels == NULL)    {        LOG("Failed to get texture buffer.");        return 0;    }    newTexture->mData = new unsigned char[newTexture->mWidth * newTexture->mHeight * newTexture->mChannelCount];    unsigned char* textureData = (unsigned char*) pixels;    int rowSize = newTexture->mWidth * newTexture->mChannelCount;    for (int r = 0; r < newTexture->mHeight; ++r)    {        memcpy(newTexture->mData + rowSize * r, pixels + rowSize * (newTexture->mHeight - 1 - r), newTexture->mWidth * 4);    }    // Release:    /**     * 当你对数组的存取完成后,要确保调用相应的ReleaseXXXArrayElements函数,     * 参数是对应Java数组和GetXXXArrayElements返回的指针。     * 如果必要的话,这个释放函数会复制你做的任何变化(这样它们就反射到java数组),然后释放所有相关的资源。     */    env->ReleaseByteArrayElements(pixelBuffer, pixels, 0);        return newTexture;}


 

表1

表2