c反射调用java动态注册的各个方法模板

记录一下c发射调用Java方法的模板,方便以后使用。

 分别为头文件,.cpp文件,以及一个调用举例

//头文件 JDCNReflexJava.h
#ifndef JDCNSAMPLE_CURL_JDCNREFLEXJAVA_H
#define JDCNSAMPLE_CURL_JDCNREFLEXJAVA_H

#include <jni.h>
#include <string>

#ifdef __cplusplus
extern "C" {
#endif
static JavaVM *g_JavaVM = NULL;//定义一个全局Java VM引用对象
static jobject g_InterfaceObject = 0;//定义一个全局Java object对象,对于java层的类对象
static const char *g_JavaClassName = "com/jdcn/sdk/LiveSDKUtil";
/*
typedef enum JDCNReflexType {
    CLivePrepareSuccess = 2000,
    CLivePrepareFail= 2001,
    CLiveSuccess = 2002,
    CLiveFail = 2003,
    CFaceLost = 2004,
    CFacePose = 2005,
    CLiveDidFindFace = 2006,
    CLiveWillCropFace = 2007,
    CLiveDidCropFace = 2008,
    CLiveDidCropFaceFail = 2009,
    CLiveActionChange = 2010,
    CLiveActionFinish = 2011,
};*/
namespace jdcn {
    namespace reflex {
        class CNReflex {
        public:
            static void GetInterfaceObject(JavaVM *vm,JNIEnv *env, const char *path, jobject *objptr);

            static jobject getInstance(JNIEnv *env, jclass obj_class);

            static void callVoidJavaMethod(std::string methodName, std::string methodParam);

            static void callIntJavaMethod(std::string methodName, std::string methodParam,int errorCode);
            static void callLongJavaMethod(std::string methodName, std::string methodParam,long numberParam);
            static void callStringJavaMethod(std::string methodName, std::string methodParam,char* string);
            static void callFloatArrayJavaMethod(std::string methodName, std::string methodParam,jfloatArray );
            static void callFacePropertyJavaMethod(std::string methodName, std::string methodParam,int, int, jfloatArray );
        };
    }
}

#ifdef __cplusplus
}
#endif
#endif //JDCNSAMPLE_CURL_JDCNREFLEXJAVA_H

.cpp文件 

//实现.cpp文件 JDCNReflexJava.cpp
#include <cstring>
#include "JDCNReflexJava.h"

using namespace jdcn;
using namespace reflex;
void CNReflex::GetInterfaceObject(JavaVM *vm,JNIEnv *env, const char *path, jobject *objptr) {
    jclass cls = env->FindClass(path);
    if (!cls) {
        return;
    }
    jmethodID constr = env->GetMethodID(cls, "<init>", "()V");
    if (!constr) {
        env->DeleteLocalRef(cls);
        return;
    }
    jobject obj = env->NewObject(cls, constr);
    if (!obj) {
        env->DeleteLocalRef(cls);
        return;
    }

    (*objptr) = env->NewGlobalRef(obj);

    env->DeleteLocalRef(cls);
    env->DeleteLocalRef(obj);
    g_JavaVM = vm;
}
jobject CNReflex::getInstance(JNIEnv *env, jclass obj_class) {
    jmethodID c_id = env->GetMethodID(obj_class, "<init>", "()V");
    jobject obj = env->NewObject(obj_class, c_id);
    return obj;
}

/**
 * C字符串转java字符串
 * ###需要主动释放内存 jsret###
 * */
jstring CharToJstring(JNIEnv* env, const char* pStr){
    int        strLen    = strlen(pStr);
    jclass     jstrObj   = env->FindClass("java/lang/String");
    jmethodID  methodId  = env->GetMethodID(jstrObj, "<init>", "([BLjava/lang/String;)V");
    jbyteArray byteArray = env->NewByteArray(strLen);
    jstring    encode    = env->NewStringUTF("utf-8");

    env->SetByteArrayRegion(byteArray, 0, strLen, (jbyte*)pStr);

    jstring jsret = (jstring)env->NewObject(jstrObj, methodId, byteArray, encode);

    env->DeleteLocalRef(byteArray);
    env->DeleteLocalRef(encode);
    //env->DeleteLocalRef(methodId);
    env->DeleteLocalRef(jstrObj);

    return jsret;
}
void CNReflex::callVoidJavaMethod(std::string methodName, std::string methodParam) {
    if (g_JavaVM == NULL) {
        return;
    }
    int status;
    JNIEnv *env = NULL;
    bool isAttached = false;

    status = g_JavaVM->GetEnv((void **) &env, JNI_VERSION_1_6);

    if (status < 0)  //
    {
        status = g_JavaVM->AttachCurrentThread(&env, NULL);
        if (status < 0) {
            return;
        }
        isAttached = true;
    }

    if (isAttached)  //
    {
        jclass cls = env->GetObjectClass(g_InterfaceObject);
        if (cls != 0) {

            jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallStaticVoidMethod(cls, mid);
            }
            env->DeleteLocalRef(cls);
        }
        g_JavaVM->DetachCurrentThread();
    } else {
        jclass cls = env->FindClass(g_JavaClassName);
        if (cls != 0) {

            jobject obj = getInstance(env, cls);
            jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallVoidMethod(obj, mid);
            }
            env->DeleteLocalRef(cls);
            env->DeleteLocalRef(obj);
        }
    }
}

void CNReflex::callIntJavaMethod(std::string methodName, std::string methodParam,int errorCode) {
    if (g_JavaVM == NULL) {
        return;
    }
    int status;
    JNIEnv *env = NULL;
    bool isAttached = false;

    status = g_JavaVM->GetEnv((void **) &env, JNI_VERSION_1_6);

    if (status < 0) {
        status = g_JavaVM->AttachCurrentThread(&env, NULL);
        if (status < 0) {
            return;
        }
        isAttached = true;
    }

    if (isAttached)  //
    {
        jclass cls = env->GetObjectClass(g_InterfaceObject);
        if (cls != 0) {

            jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallStaticVoidMethod(cls, mid, errorCode);
            }
            env->DeleteLocalRef(cls);
        }
        g_JavaVM->DetachCurrentThread();
    } else {
        jclass cls = env->FindClass(g_JavaClassName);
        if (cls != 0) {

            jobject obj = getInstance(env, cls);
            jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallVoidMethod(obj, mid, errorCode);
            }
            env->DeleteLocalRef(cls);
            env->DeleteLocalRef(obj);
        }
    }
}
void CNReflex::callLongJavaMethod(std::string methodName, std::string methodParam,long numberParam) {
    if (g_JavaVM == NULL) {
        return;
    }
    int status;
    JNIEnv *env = NULL;
    bool isAttached = false;

    status = g_JavaVM->GetEnv((void **) &env, JNI_VERSION_1_6);

    if (status < 0) {
        status = g_JavaVM->AttachCurrentThread(&env, NULL);
        if (status < 0) {
            return;
        }
        isAttached = true;
    }

    if (isAttached)  //
    {
        jclass cls = env->GetObjectClass(g_InterfaceObject);
        if (cls != 0) {

            jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallStaticVoidMethod(cls, mid, numberParam);
            }
            env->DeleteLocalRef(cls);
        }
        g_JavaVM->DetachCurrentThread();
    } else {
        jclass cls = env->FindClass(g_JavaClassName);
        if (cls != 0) {

            jobject obj = getInstance(env, cls);
            jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallVoidMethod(obj, mid, numberParam);
            }
            env->DeleteLocalRef(cls);
            env->DeleteLocalRef(obj);
        }
    }
}
void CNReflex::callStringJavaMethod(std::string methodName, std::string methodParam,char* string) {
    if (g_JavaVM == NULL) {
        return;
    }
    int status;
    JNIEnv *env = NULL;
    bool isAttached = false;

    status = g_JavaVM->GetEnv((void **) &env, JNI_VERSION_1_6);

    if (status < 0) {
        status = g_JavaVM->AttachCurrentThread(&env, NULL);
        if (status < 0) {
            return;
        }
        isAttached = true;
    }

    if (isAttached)  //
    {
        jclass cls = env->GetObjectClass(g_InterfaceObject);
        if (cls != 0) {

            jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                jstring path = CharToJstring(env,string);
                env->CallStaticVoidMethod(cls, mid, path);
            }
            env->DeleteLocalRef(cls);
        }
        g_JavaVM->DetachCurrentThread();
    } else {
        jclass cls = env->FindClass(g_JavaClassName);
        if (cls != 0) {

            jobject obj = getInstance(env, cls);
            jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                jstring path = CharToJstring(env,string);

                env->CallVoidMethod(obj, mid, path);
            }
            env->DeleteLocalRef(cls);
            env->DeleteLocalRef(obj);
        }
    }
}
void CNReflex::callFloatArrayJavaMethod(std::string methodName, std::string methodParam,jfloatArray value) {
    if (g_JavaVM == NULL) {
        return;
    }
    int status;
    JNIEnv *env = NULL;
    bool isAttached = false;

    status = g_JavaVM->GetEnv((void **) &env, JNI_VERSION_1_6);

    if (status < 0) {
        status = g_JavaVM->AttachCurrentThread(&env, NULL);
        if (status < 0) {
            return;
        }
        isAttached = true;
    }

    if (isAttached)  //
    {
        jclass cls = env->GetObjectClass(g_InterfaceObject);
        if (cls != 0) {

            jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallStaticVoidMethod(cls, mid, value);
            }
            env->DeleteLocalRef(cls);
        }
        g_JavaVM->DetachCurrentThread();
    } else {
        jclass cls = env->FindClass(g_JavaClassName);
        if (cls != 0) {

            jobject obj = getInstance(env, cls);
            jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallVoidMethod(obj, mid, value);
            }
            env->DeleteLocalRef(cls);
            env->DeleteLocalRef(obj);
        }
    }
}
void CNReflex::callFacePropertyJavaMethod(std::string methodName, std::string methodParam,int age, int gender, jfloatArray value) {
    if (g_JavaVM == NULL) {
        return;
    }
    int status;
    JNIEnv *env = NULL;
    bool isAttached = false;

    status = g_JavaVM->GetEnv((void **) &env, JNI_VERSION_1_6);

    if (status < 0) {
        status = g_JavaVM->AttachCurrentThread(&env, NULL);
        if (status < 0) {
            return;
        }
        isAttached = true;
    }

    if (isAttached)  //
    {
        jclass cls = env->GetObjectClass(g_InterfaceObject);
        if (cls != 0) {

            jmethodID mid = env->GetStaticMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallStaticVoidMethod(cls, mid, age,gender, value);
            }
            env->DeleteLocalRef(cls);
        }
        g_JavaVM->DetachCurrentThread();
    } else {
        jclass cls = env->FindClass(g_JavaClassName);
        if (cls != 0) {

            jobject obj = getInstance(env, cls);
            jmethodID mid = env->GetMethodID(cls, methodName.c_str(), methodParam.c_str());
            if (mid != 0) {
                env->CallVoidMethod(obj, mid, age,gender, value);
            }
            env->DeleteLocalRef(cls);
            env->DeleteLocalRef(obj);
        }
    }
}

 Nativa方法调用的例子:callJDCNCatchImagePath为java层方法名,第二个位java方法传参与返回,name为返回参数

CNReflex::callStringJavaMethod("callJDCNCatchImagePath", "(Ljava/lang/String;)V", name);

Java层对应的函数: 

    public void callJDCNCatchImagePath(String path) {
        File file = new File(path);
        if (file.exists()) {
            if (mJDCNLiveCallbak != null) {
                mJDCNLiveCallbak.get().JDCNImagePathCaught(path);
            }
//            Bitmap bitmap = null;
//            String base64 = BitmapUtil.rotateImgToBase64(path, bitmap, "", 90);
//            if (mJDCNLiveCallbak != null && null != base64) {
//                mJDCNLiveCallbak.get().JDCNLiveSuccess(base64);
//            }
            file.delete();
        }
    }

猜你喜欢

转载自blog.csdn.net/u013634213/article/details/81113380
今日推荐