读书人

用例证学习 c++范型编程(模板元)

发布时间: 2013-01-28 11:49:56 作者: rapoo

用例子学习 c++范型编程(模板元)

此文版权属于作者用例证学习 c++范型编程(模板元)所有,任何人、媒体或者网站转载、借用都必须征得作者本人同意!

例子用一个实例:通过 jni 接口读取 java 对象。

#include <jni.h>//=============================================================// 场景 1,最常见namespace t1 {    //=============================================================#if 0    // java 类    public class Frame {        public int width = 0;        public int height = 0;    }#endif    class Frame1 {    public:        jint width;        jint height;    };    //-------------------------    void getFrame(JNIEnv* env, jobject jframe, Frame1& frame) {        jclass cls = env->GetObjectClass(jframe);        {            jfieldID field = env->GetFieldID(cls, "width", "I");            frame.width = env->functions->GetIntField(env, jframe, field);        }        {            jfieldID field = env->GetFieldID(cls, "height", "I");            frame.height = env->functions->GetIntField(env, jframe, field);        }    }    //=============================================================    // 修改 Frame 的数据成员 height 的类型,对应的代码修改如下#if 0    // java 类    public class Frame {        public int width = 0;        public long height = 0;    }#endif    class Frame2 {    public:        jint width;        jlong height;    };    //-------------------------    void getFrame(JNIEnv* env, jobject jframe, Frame2& frame) {        jclass cls = env->GetObjectClass(jframe);        {            jfieldID field = env->GetFieldID(cls, "width", "I");            frame.width = env->functions->GetIntField(env, jframe, field);        }        {            jfieldID field = env->GetFieldID(cls, "height", "J");            frame.height = env->functions->GetLongField(env, jframe, field);        }    }} // namespace t1//=============================================================// 场景 2,比较常见 c 风格或者 c++ 风格namespace t2 {#if 0    // Frame java implement    public class Frame {        public int width = 0;        public long height = 0;    }#endif    class Frame {    public:        jint width;        jlong height;    };    //=============================================================    // 最普通,最直白    void getFrame(JNIEnv* env, jobject jframe, Frame& frame) {        jclass cls = env->GetObjectClass(jframe);        {            jfieldID field = env->GetFieldID(cls, "width", "I");            frame.width = env->functions->GetIntField(env, jframe, field);        }        {            jfieldID field = env->GetFieldID(cls, "height", "J");            frame.height = env->functions->GetLongField(env, jframe, field);        }    }    //=============================================================    // c 风格 1    void getField_jint(JNIEnv* env, jobject jframe, char const* name, jint* v) {        jclass cls = env->GetObjectClass(jframe);        jfieldID field = env->GetFieldID(cls, name, "I");        *v = env->functions->GetIntField(env, jframe, field);    }    void getField_jlong(JNIEnv* env, jobject jframe, char const* name, jlong* v) {        jclass cls = env->GetObjectClass(jframe);        jfieldID field = env->GetFieldID(cls, name, "J");        *v = env->functions->GetLongField(env, jframe, field);    }    //-------------------------    void getFrame2(JNIEnv* env, jobject jframe, Frame& frame) {        getField_jint(env, jframe, "width", &frame.width);        getField_jlong(env, jframe, "height", &frame.height);    }    //=============================================================    // c 风格 2    enum FieldType{        FT_INT,        FT_LONG,    };    union Field {        jint i;        jlong l;    };    void getField(JNIEnv* env, jobject jframe, char const* name, FieldType type, Field* v) {        jclass cls = env->GetObjectClass(jframe);        jfieldID field;        switch(type)        {            case FT_INT:                field = env->GetFieldID(cls, name, "I");                v->i = env->functions->GetIntField(env, jframe, field);                break;            case FT_LONG:                field = env->GetFieldID(cls, name, "J");                v->l = env->functions->GetLongField(env, jframe, field);                break;        }    }    //-------------------------    void getFrame3(JNIEnv* env, jobject jframe, Frame& frame) {        Field v;        getField(env, jframe, "width", FT_INT, &v);        frame.width = v.i;        getField(env, jframe, "height", FT_LONG, &v);        frame.height = v.l;    }    //=============================================================    // c++ 风格    void getField(JNIEnv* env, jobject jframe, char const* name, jint& v) {        jclass cls = env->GetObjectClass(jframe);        jfieldID field = env->GetFieldID(cls, name, "I");        v = env->functions->GetIntField(env, jframe, field);    }    void getField(JNIEnv* env, jobject jframe, char const* name, jlong& v) {        jclass cls = env->GetObjectClass(jframe);        jfieldID field = env->GetFieldID(cls, name, "J");        v = env->functions->GetLongField(env, jframe, field);    }    //-------------------------    void getFrame4(JNIEnv* env, jobject jframe, Frame& frame) {        getField(env, jframe, "width", frame.width);        getField(env, jframe, "height", frame.height);    }} // namespace t2//=============================================================// 场景 3,现代 c++ 风格,采用范型编程实现namespace t3 {#if 0    // Frame java implement    public class Frame {        public int width = 0;        public long height = 0;    }#endif    class Frame {    public:        jint width;        jlong height;    };    template<typename T>    class Field {    public:        static char const* SIGNATURE;        static void GetField(JNIEnv* env, jobject obj, jfieldID field, T& v);    };    template<> char const* Field<jint>::SIGNATURE = "I";    template<> inline void Field<jint>::GetField(JNIEnv* env, jobject obj, jfieldID field, jint& v) {        v = env->functions->GetIntField(env, obj, field);    }    template<> char const* Field<jlong>::SIGNATURE = "J";    template<> inline void Field<jlong>::GetField(JNIEnv* env, jobject obj, jfieldID field, jlong& v) {        v = env->functions->GetLongField(env, obj, field);    }    template<typename T>    void getField(JNIEnv* env, jobject jframe, char const* name, T& v) {        jclass cls = env->GetObjectClass(jframe);        jfieldID field = env->GetFieldID(cls, name, Field<T>::SIGNATURE);        Field<T>::GetField(env, jframe, field, v);        v = env->functions->GetIntField(env, jframe, field);    }    //-------------------------    void getFrame(JNIEnv* env, jobject jframe, Frame& frame) {        getField(env, jframe, "width", frame.width);        getField(env, jframe, "height", frame.height);    }} // namespace t3

读书人网 >编程

热点推荐