首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用C++模板实现类型到对象方法调用的映射?

如何使用C++模板实现类型到对象方法调用的映射?
EN

Stack Overflow用户
提问于 2018-08-08 22:24:55
回答 1查看 69关注 0票数 1

我想使用C++模板在JNI代码中为java数组开发(另一个)包装器。主要目标是提高我的C++模板编程技能。

我使用Android NDK编译代码(编译器是Clang 6.0.2)

到目前为止,我已经成功地做到了:

代码语言:javascript
复制
#include <jni.h>

template <typename T>
struct TypeToObjectType;

template <>
struct TypeToObjectType<jbyteArray>
{
    typedef jbyte type;
};

template <>
struct TypeToObjectType<jintArray>
{
    typedef jint type;
};

template <typename javaArrayT, typename nativeT>
class Java_array{
    JNIEnv *env;
    jboolean is_copy;
    jsize array_len;

    javaArrayT array;
    typename TypeToObjectType<javaArrayT>::type *array_elements;

public:
    Java_array(JNIEnv *_env, javaArrayT _array)
        : env(_env)
        , array(_array)
        , array_len(-1)
    {
        array_elements = env->GetByteArrayElements(array, &is_copy);  //TODO: make it resolving automatically to other primitives
    }

    ~Java_array() {
        env->ReleaseByteArrayElements(array, array_elements, JNI_ABORT);
    }

    jsize len(){
        if (array_len < 0)
           array_len = env->GetArrayLength(array);
        return array_len;
    }

    operator nativeT* () const {
        return reinterpret_cast<nativeT*>(array_elements);
    };
};

这不适用于int[]float[]和除byte[]以外的其他数组,因为该类调用GetByteArrayElements

我使用struct TypeToObjectType来建立映射jbyteArray -> jbytejintArray -> jint

此映射缺少java类型-> JEnv方法调用的部分,即jbyteArray -> (GetByteArrayElementsReleaseByteArrayElements),jintArray -> (GetIntArrayElementsReleaseIntArrayElements)`

我该怎么做呢?

如何使用C++11、C++14的功能改进我的代码?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-08 23:55:54

您可以将指向成员的指针添加到您的特征。

代码语言:javascript
复制
template <>
struct TypeToObjectType<jbyteArray>
{
    typedef jbyte type;
    static constexpr jbyte * (JNIEnv::* const GetElements)(jbyteArray, jboolean *) = &JNIEnv::GetByteArrayElements;
    static constexpr void (JNIEnv::* const ReleaseElements)(jbyteArray, jbyte *, decltype(JNI_ABORT)) = &JNIEnv::ReleaseByteArrayElements;
};

template <>
struct TypeToObjectType<jintArray>
{
    typedef jint type;
    static constexpr jint * (JNIEnv::* const GetElements)(jintArray, jboolean *) = &JNIEnv::GetIntArrayElements;
    static constexpr void (JNIEnv::* const ReleaseElements)(jintArray, jint *, decltype(JNI_ABORT)) = &JNIEnv::ReleaseIntArrayElements;
};

您可以通过稍微不同的语法调用它

代码语言:javascript
复制
Java_array(JNIEnv *_env, javaArrayT _array)
    : env(_env)
    , array(_array)
    , array_len(-1)
{
    array_elements = (env->*TypeToObjectType<javaArrayT>::GetElements)(array, &is_copy);
}

~Java_array() {
    (env->*TypeToObjectType<javaArrayT>::ReleaseElements)(array, array_elements, JNI_ABORT);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51749136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档