首页 > 代码库 > JNI实现JAVA和C++互相调用

JNI实现JAVA和C++互相调用

SDK.h

 1 #ifndef SDK_H 2 #define SDK_H 3  4 #include "AsyncProxy.h" 5 #include "Module.h" 6 #include <map> 7 #include <vector> 8 #include <string> 9 using std::map;10 using std::vector;11 using std::string;12 13 14 class SDK15 {16 private:17     vector<Module*> m_modules;18     AsyncProxy* mp_asyncProxy;19     map<string,Method*> m_methodIndex;20 private:21     Method* checkMethod(string methodName, map<std::string, std::string> &params);22     void init();23 public:24     SDK();25     SDK(CallBackFun* p_exceptionFun);26     ~SDK();27     void addModule(Module* p_module);28     string request(string methodName, map<string,string>& params);29     void requestAsync(string methodName, map<string, string> &params, CallBackFun* p_callBack = NULL);30 };31 32 #endif

CallBackFun.h

1 class CallBackFun2 {3 public:4     virtual ~CallBackFun(){}5     virtual void callBack(string& result){SDK_DEBUG("%s",result.c_str());}6 };

main.cpp

#include <string.h>#include <jni.h>#include "core/SDK.h"static JavaVM* p_vm = NULL;JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){    p_vm = vm;    return JNI_VERSION_1_6;}class JavaCallBackFun:public CallBackFun{private:    jobject m_object;    jstring m_method;    static const char* m_signature;    bool m_destroy;public:    JavaCallBackFun( JNIEnv* env,jobject object,jstring method,bool destroy)    {        m_object = env->NewGlobalRef(object);        m_method = (jstring)env->NewGlobalRef(method);        m_destroy = destroy;    }        ~JavaCallBackFun()    {        if(m_destroy == false)        {            JNIEnv* env;            p_vm->AttachCurrentThread(&env, NULL);            env->DeleteGlobalRef(m_object);            env->DeleteGlobalRef(m_method);        }    }        void callBack(string& result)    {        JNIEnv* env;        p_vm->AttachCurrentThread(&env, NULL);        jstring jresult = env->NewStringUTF(result.c_str());        const char* methodStr = env->GetStringUTFChars(m_method, 0);        jclass clazz = env->GetObjectClass(m_object);        jmethodID  methodID = env -> GetMethodID(clazz,methodStr,m_signature);        env -> CallVoidMethod(m_object,methodID,jresult);        env -> ReleaseStringUTFChars(m_method,methodStr);        if(m_destroy == true)        {            env->DeleteGlobalRef(m_object);            env->DeleteGlobalRef(m_method);        }    }};const char* JavaCallBackFun::m_signature = "(Ljava/lang/String;)V";extern "C" {    JNIEXPORT jlong JNICALL Java_com_pptv_sdk_CommonSDK_initSDKNative( JNIEnv* env,jobject thiz,jobject callBackObj,jstring exceptionFun);    JNIEXPORT void JNICALL Java_com_pptv_sdk_CommonSDK_cleanSDKNative( JNIEnv* env,jobject thiz,jlong sdkptr);    JNIEXPORT jstring JNICALL Java_com_pptv_sdk_CommonSDK_requestNative( JNIEnv* env,jobject thiz,jlong sdkptr,jstring methodName,                                                                         jobjectArray paramKeys,jobjectArray paramValues);    JNIEXPORT void JNICALL Java_com_pptv_sdk_CommonSDK_requestAsyncNative( JNIEnv* env,jobject thiz,jlong sdkptr,jstring methodName,                                                jobjectArray paramKeys,jobjectArray paramValues,jobject callBackObj,jstring callBackMethod);};JNIEXPORT jlong JNICALL Java_com_pptv_sdk_CommonSDK_initSDKNative( JNIEnv* env,jobject thiz,jobject callBackObj,jstring exceptionFun){    JavaCallBackFun* p_callBack = new JavaCallBackFun(env,callBackObj,exceptionFun,false);    return (jlong)new SDK(p_callBack);}JNIEXPORT void JNICALL Java_com_pptv_sdk_CommonSDK_cleanSDKNative( JNIEnv* env,jobject thiz,jlong sdkptr){    SDK* p_sdk = (SDK*)sdkptr;    delete p_sdk;}JNIEXPORT jstring JNICALL Java_com_pptv_sdk_CommonSDK_requestNative( JNIEnv* env,jobject thiz,jlong sdkptr,jstring methodName,                                                                     jobjectArray paramKeys,jobjectArray paramValues){    SDK* p_sdk = (SDK*)sdkptr;    const char * methodNameStr = env->GetStringUTFChars( methodName, 0);    //init param map    jstring jkey,jvalue;    jsize keysLen=env->GetArrayLength(paramKeys);    map<string,string> params;    for(jsize i=0;i<keysLen;++i)    {        jkey = (jstring)(env->GetObjectArrayElement(paramKeys,i));        jvalue = (jstring)(env->GetObjectArrayElement(paramValues,i));        const char *key = env->GetStringUTFChars(jkey, 0);        const char *value = http://www.mamicode.com/env->GetStringUTFChars(jvalue,0);        params[string(key)] = string(value);        env->ReleaseStringUTFChars(jkey,key);        env->ReleaseStringUTFChars(jvalue,value);    }        string result = p_sdk->request(methodNameStr,params);    env->ReleaseStringUTFChars(methodName,methodNameStr);    return env->NewStringUTF(result.c_str());}JNIEXPORT void JNICALL Java_com_pptv_sdk_CommonSDK_requestAsyncNative( JNIEnv* env,jobject thiz,jlong sdkptr,jstring methodName,                                            jobjectArray paramKeys,jobjectArray paramValues,jobject callBackObj,jstring callBackMethod){    SDK* p_sdk = (SDK*)sdkptr;    const char * methodNameStr = env->GetStringUTFChars(methodName, 0);    //init param map    jstring jkey,jvalue;    jsize keysLen=env->GetArrayLength(paramKeys);    map<string,string> params;    for(jsize i=0;i<keysLen;++i)    {        jkey = (jstring)(env->GetObjectArrayElement(paramKeys,i));        jvalue = (jstring)(env->GetObjectArrayElement(paramValues,i));        const char *key = env->GetStringUTFChars(jkey, 0);        const char *value = http://www.mamicode.com/env->GetStringUTFChars(jvalue,0);        params[string(key)] = string(value);        env->ReleaseStringUTFChars(jkey,key);        env->ReleaseStringUTFChars(jvalue,value);    }    //init callback fun    JavaCallBackFun* p_callBack = NULL;    if(callBackObj != NULL && callBackMethod != NULL)    {        p_callBack = new JavaCallBackFun(env,callBackObj,callBackMethod,true);    }    //async call     p_sdk->requestAsync(methodNameStr,params,p_callBack);    env->ReleaseStringUTFChars(methodName,methodNameStr);}

CommonSDK.java

 1 package com.pptv.sdk; 2 import java.util.Map; 3  4 /** 5  * CommonSDK is a common interface to interact with sdk.so 6  * <p> 7  * CommonSDK use jni to call native method written by C++,and it  8  * provide a common interface for Java developer.You can directly 9  * call the common interface,but it is suggested to use the special10  * interface based on CommonSDK,which is more understandable.  11  * @author      guoxiaoqian12  */13 public class CommonSDK implements SDKCallBack14 {15     static16     {17         System.loadLibrary("sdk");18     }19     20     //Exception Call Back21     @Override22     public void callBack(String result)23     {24         // TODO Auto-generated method stub25         System.out.println("Exception occured: "+result);26     }27     28     private long m_sdkHandle;29     private static final CommonSDK m_sdk = new CommonSDK();30     31     private CommonSDK()32     {33         m_sdkHandle = initSDKNative(this,SDKCallBack.callBackName);34     }35     36     37     /** 38      * getInstance()     get a singleton CommonSDK object39      * @return          CommonSDK object40      */41     public static CommonSDK getInstance()42     {43         return m_sdk;44     }45     46     protected void finalize()47     {48         cleanSDKNative(m_sdkHandle);49     }50     51     /** 52      * request()             sync request53      * @param methodName    specify the method to call54      * @param params        multi params in key-value map55      * @return              json string containing complex result56      */57     public String request(String methodName,Map<String,String> params)58     {59         String[] keyArr = new String[params.size()];60         String[] valueArr = new String[params.size()];61         int i=0;62         for(Map.Entry<String, String> entry:params.entrySet())63         {    64             keyArr[i] = entry.getKey();65             valueArr[i] = entry.getValue();66             ++i;67         }68         return requestNative(m_sdkHandle,methodName,keyArr,valueArr);69     }70     71     /** 72      * requestAsync()         async request73      * @param methodName    specify the method to call74      * @param params        multi params in key-value map75      * @param callBackObj    specify the obj to handle callback from sdk76      */77     public void requestAsync(String methodName,Map<String,String> params,SDKCallBack callBackObj)78     {79         String[] keyArr = new String[params.size()];80         String[] valueArr = new String[params.size()];81         int i=0;82         for(Map.Entry<String, String> entry:params.entrySet())83         {    84             keyArr[i] = entry.getKey();85             valueArr[i] = entry.getValue();86             ++i;87         }88         requestAsyncNative(m_sdkHandle,methodName,keyArr,valueArr,callBackObj,callBackObj==null?null:SDKCallBack.callBackName);89     }90     91     private native long initSDKNative(Object callBackObject,String exceptionFun);92     private native void cleanSDKNative(long sdkHandle);93     private native String requestNative(long sdkHandle,String methodName,String keys[],String values[]);94     private native void requestAsyncNative(long sdkHandle,String methodName,String keys[],String values[],Object callBackObject,String callBackFunName);95 96 }

SDKCallBack.java

 1 package com.pptv.sdk; 2  3 /** 4  * SDKCallBack is an interface that you must implements when 5  * you want to have an object to handle the callback form sdk. 6  * @author      guoxiaoqian 7  */ 8 public interface SDKCallBack { 9     public final String callBackName = "callBack";10     public abstract void callBack(String result);11 }