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 SDK
15 {
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 CallBackFun
2 {
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 = 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 = 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 special
10  * interface based on CommonSDK,which is more understandable.
11  * @author      guoxiaoqian
12  */
13 public class CommonSDK implements SDKCallBack
14 {
15     static
16     {
17         System.loadLibrary("sdk");
18     }
19
20     //Exception Call Back
21     @Override
22     public void callBack(String result)
23     {
24         // TODO Auto-generated method stub
25         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 object
39      * @return          CommonSDK object
40      */
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 request
53      * @param methodName    specify the method to call
54      * @param params        multi params in key-value map
55      * @return              json string containing complex result
56      */
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 request
73      * @param methodName    specify the method to call
74      * @param params        multi params in key-value map
75      * @param callBackObj    specify the obj to handle callback from sdk
76      */
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 }

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

时间: 2024-07-29 08:41:11

JNI实现JAVA和C++互相调用的相关文章

JNI(Java本地方法调用)

windows:中C/C++是.dll表示调用的动态链接库,而linux是.so表示动态链接库 JNI(Java Native Interface)的书写步骤 ·编写带有native声明的方法的java类      ·使用javac命令编译所编写的java类      ·使用javah ?jni java类名生成扩展名为h的头文件      ·使用C/C++(或者其他编程想语言)实现本地方法      ·将C/C++编写的文件生成动态连接库 JNI(Java Native Interface)调

ndk学习17: jni之Java调用C&C++

一.Hello World 1. 定义函数原型 native关键字定义的函数即为jni函数 2.生成头文件 切换到src目录执行: (这个过程可以写脚本自动完成,比如自动拷贝到jni目录) javah -jni 包名.类名 在根目录下生成: org_bing_testjni_MainActivity.h 3. 工程中添加jni代码 工程右键->添加native code->输入名字->finish 多了如下文 新建一个Application.mk,配置相关选项(详细查看ndk有关Appl

Java通过jni技术支持c、c++调用使用整理

最近在公司搞终端5.0,说要对c++版本sdk封装一个java版的sdk,可是团队没有搞java的,于是赶鸭子上架,临时学习几天,整了一下:感觉还挺有意思的,于是整理一下: 为什么要使用java支持对c.c++的调用? 众所周知Java语言是一门支持跨平台解释型语言:#.java通过javac编译生成生成#.class字节码,运行过程依赖java虚拟机执行字节码生成虚拟机的执行指令,最终通过虚拟机操控所在平台,完成其设计的功能:其优点很明显,支持跨平台:其缺点也很明显,执行效率底,并且不支持平台

JNI之JAVA调用C++接口

1.JNI定义(来自百度百科) JNI是Java Native Interface的缩写,中文为JAVA本地调用.从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了. 2.java通过JNI调用c++接口步骤 1).创建java包.类 此处创建 包myJNI,类TestJNI pac

【我的Android进阶之旅】Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法

错误描述 今天使用第三方的so库时候,调用JNI方法时出现了错误.报错如下所示: 11-01 16:39:20.979 4669-4669/com.netease.xtc.cloudmusic E/art: No implementation found for void com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(android.content.Context) (tried Java_com_netease_xt

Android JNI之JAVA与C++对象建立对称关联(JNI优化设计,确保JNI调用的稳定性)

转载请声明:原文转自:http://www.cnblogs.com/xiezie/p/5930503.html Android JNI之JAVA与C++对象建立对称关联 1.JAVA对象持有C++对象的指针 在JAVA类中创建一个int类型的变量(如int mObj),用于储存C++对象的指针 在创建C++对象(如MyCPlusObj)的本地方法中,将C++对象的指针存入JAVA变量中(mObj) JNIEXPORT void JNICALL Java_nativeMethod (JNIEnv

Android NDK开发(1)----- Java与C互相调用实例详解

链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/13/2394153.html 一.概述 对于大部分应用开发者来说可能都不怎么接触到NDK,但如果涉及到硬件操作的话就不得不使用NDK了.使用NDK还有另一个原因,就是C/C++的效率比较高,因此我们可以把一些耗时的操作放在NDK中实现. 关于java与c/c++的互相调用,网上有一大堆的文章介绍.但仔细观察可以发现,基本都是讲在java中调用一个本地方法,然后由该本地方法直接返回一个参数给ja

android 学习随笔二十七(JNI:Java Native Interface,JAVA原生接口 )

JNI(Java Native Interface,JAVA原生接口) 使用JNI可以使Java代码和其他语言写的代码(如C/C++代码)进行交互. 问:为什么要进行交互? 首先,Java语言提供的类库无法满足要求,且在数学运算,实时渲染的游戏上,音视频处理等方面上与C/C++相比效率稍低. 然后,Java语言无法直接操作硬件,C/C++代码不仅能操作硬件而且还能发挥硬件最佳性能. 接着,使用Java调用本地的C/C++代码所写的库,省去了重复开发的麻烦,并且可以利用很多开源的库提高程序效率.

JAVA和.NET互调用

通过接口实现JAVA和.NET互调用-JNInterface 使用C#编程多年,也十分感激微软在语言架构.语法糖.编辑器等方面给自己带来的便利.但因为最近工作中有接触到JAVA,渐渐地发现的确像大家说的那样,JAVA的生态很好,要找点什么几乎都有现成的,于是自然就想到了能不能用.NET来调用JAVA. 具了解,有个JNBridge的软件,可以"Bridge any Java with any .NET, anywhere",也许很好用,但是付费的,不喜欢. 又了解了一下其他的方法,都不