记录一下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();
}
}