JNI实现JAVA和C++互相调用
SDK.h
#ifndef SDK_H
#define SDK_H #include "AsyncProxy.h"
#include "Module.h"
#include <map>
#include <vector>
#include <string>
using std::map;
using std::vector;
using std::string; class SDK
{
private:
vector<Module*> m_modules;
AsyncProxy* mp_asyncProxy;
map<string,Method*> m_methodIndex;
private:
Method* checkMethod(string methodName, map<std::string, std::string> ¶ms);
void init();
public:
SDK();
SDK(CallBackFun* p_exceptionFun);
~SDK();
void addModule(Module* p_module);
string request(string methodName, map<string,string>& params);
void requestAsync(string methodName, map<string, string> ¶ms, CallBackFun* p_callBack = NULL);
}; #endif
CallBackFun.h
class CallBackFun
{
public:
virtual ~CallBackFun(){}
virtual void callBack(string& result){SDK_DEBUG("%s",result.c_str());}
};
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, );
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, );
//init param map
jstring jkey,jvalue;
jsize keysLen=env->GetArrayLength(paramKeys);
map<string,string> params;
for(jsize i=;i<keysLen;++i)
{
jkey = (jstring)(env->GetObjectArrayElement(paramKeys,i));
jvalue = (jstring)(env->GetObjectArrayElement(paramValues,i));
const char *key = env->GetStringUTFChars(jkey, );
const char *value = env->GetStringUTFChars(jvalue,);
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, );
//init param map
jstring jkey,jvalue;
jsize keysLen=env->GetArrayLength(paramKeys);
map<string,string> params;
for(jsize i=;i<keysLen;++i)
{
jkey = (jstring)(env->GetObjectArrayElement(paramKeys,i));
jvalue = (jstring)(env->GetObjectArrayElement(paramValues,i));
const char *key = env->GetStringUTFChars(jkey, );
const char *value = env->GetStringUTFChars(jvalue,);
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
package com.pptv.sdk;
import java.util.Map; /**
* CommonSDK is a common interface to interact with sdk.so
* <p>
* CommonSDK use jni to call native method written by C++,and it
* provide a common interface for Java developer.You can directly
* call the common interface,but it is suggested to use the special
* interface based on CommonSDK,which is more understandable.
* @author guoxiaoqian
*/
public class CommonSDK implements SDKCallBack
{
static
{
System.loadLibrary("sdk");
} //Exception Call Back
@Override
public void callBack(String result)
{
// TODO Auto-generated method stub
System.out.println("Exception occured: "+result);
} private long m_sdkHandle;
private static final CommonSDK m_sdk = new CommonSDK(); private CommonSDK()
{
m_sdkHandle = initSDKNative(this,SDKCallBack.callBackName);
} /**
* getInstance() get a singleton CommonSDK object
* @return CommonSDK object
*/
public static CommonSDK getInstance()
{
return m_sdk;
} protected void finalize()
{
cleanSDKNative(m_sdkHandle);
} /**
* request() sync request
* @param methodName specify the method to call
* @param params multi params in key-value map
* @return json string containing complex result
*/
public String request(String methodName,Map<String,String> params)
{
String[] keyArr = new String[params.size()];
String[] valueArr = new String[params.size()];
int i=;
for(Map.Entry<String, String> entry:params.entrySet())
{
keyArr[i] = entry.getKey();
valueArr[i] = entry.getValue();
++i;
}
return requestNative(m_sdkHandle,methodName,keyArr,valueArr);
} /**
* requestAsync() async request
* @param methodName specify the method to call
* @param params multi params in key-value map
* @param callBackObj specify the obj to handle callback from sdk
*/
public void requestAsync(String methodName,Map<String,String> params,SDKCallBack callBackObj)
{
String[] keyArr = new String[params.size()];
String[] valueArr = new String[params.size()];
int i=;
for(Map.Entry<String, String> entry:params.entrySet())
{
keyArr[i] = entry.getKey();
valueArr[i] = entry.getValue();
++i;
}
requestAsyncNative(m_sdkHandle,methodName,keyArr,valueArr,callBackObj,callBackObj==null?null:SDKCallBack.callBackName);
} private native long initSDKNative(Object callBackObject,String exceptionFun);
private native void cleanSDKNative(long sdkHandle);
private native String requestNative(long sdkHandle,String methodName,String keys[],String values[]);
private native void requestAsyncNative(long sdkHandle,String methodName,String keys[],String values[],Object callBackObject,String callBackFunName); }
SDKCallBack.java
package com.pptv.sdk; /**
* SDKCallBack is an interface that you must implements when
* you want to have an object to handle the callback form sdk.
* @author guoxiaoqian
*/
public interface SDKCallBack {
public final String callBackName = "callBack";
public abstract void callBack(String result);
}
JNI实现JAVA和C++互相调用的更多相关文章
- Android 通过 JNI 访问 Java 字段和方法调用
在前面的两篇文章中,介绍了 Android 通过 JNI 进行基础类型.字符串和数组的相关操作,并描述了 Java 和 Native 在类型和签名之间的转换关系. 有了之前那些基础,就可以实现 Jav ...
- Android jni c/c++线程通过CallVoidMethod调用java函数出现奔溃问题
最近在移植网络摄像机里的p2p库到android平台,需要用到jni,最近在c线程了调用java函数的时候 出现一个问题,假如在同一个线程调用java函数是没问题的,但在一个c线程了调用java函数就 ...
- Android JNI学习(三)——Java与Native相互调用
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- 【我的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/a ...
- JNI之JAVA调用C++接口
1.JNI定义(来自百度百科) JNI是Java Native Interface的缩写,中文为JAVA本地调用.从Java1.1开始,Java Native Interface(JNI)标准成为ja ...
- 通过JNI实现java调用C代码和C代码调用java的代码
一.java调用C代码 1)java中需要声明调用的函数,也就是native方法,并通过System.LoadLibrary来调用dll或者so(C代码).实例代码如下: public class H ...
- Android JNI之JAVA与C++对象建立对称关联(JNI优化设计,确保JNI调用的稳定性)
转载请声明:原文转自:http://www.cnblogs.com/xiezie/p/5930503.html Android JNI之JAVA与C++对象建立对称关联 1.JAVA对象持有C++对象 ...
- java本地方法如何调用其他程序函数,方法详解
JNI是Java Native Interface的缩写,中文为JAVA本地调用.从Java 1.1 开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许J ...
- android 学习随笔二十七(JNI:Java Native Interface,JAVA原生接口 )
JNI(Java Native Interface,JAVA原生接口) 使用JNI可以使Java代码和其他语言写的代码(如C/C++代码)进行交互. 问:为什么要进行交互? 首先,Java语言提供的类 ...
随机推荐
- 梯度下降算法以及其Python实现
一.梯度下降算法理论知识 我们给出一组房子面积,卧室数目以及对应房价数据,如何从数据中找到房价y与面积x1和卧室数目x2的关系? 为了实现监督学习,我们选择采用自变量x1.x2的线性函数来评估因变 ...
- js操作对象属性值为字符串
今天在项目开发中遇到一个没遇到过的问题,这个问题是需要对比两个对象a和b,a是一个只有一个属性的对象,b是一个含有多个属性对象,如果b中包含和a一模一样的属性名和值,则把这个一样的属性和值从b中删除了 ...
- ADAS芯片解决方案汇总
ADAS(高级辅助驾驶系统),是指利用安装于车上各式各样的传感器,在第一时间收集车内的环境数据,进行静.动态物体的辨识.侦测与追踪等技术上的处理,从而能够让驾驶者在最快的时间察觉可能发生的危险. 在过 ...
- Alpha阶段事后诸葛亮会议记录
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2324 组名:可以低头,但没必要 组长:付佳 组员:张俊余 李文涛 孙 ...
- "助成"招聘网站视频简介
我们小组为我们的作品录制了一个一分多钟的电梯介绍视频,这是视频连接,我上传到了优酷上:http://v.youku.com/v_show/id_XMzIzMTc1ODc2NA==.html?spm=a ...
- OpenFlow协议
功能 1.0版本Openflow:控制器通过Openflow协议与交换机建立了安全通道(Sceure Channel),下发流表. 1.3版本Openflow:多控制器,多流表. 用于实现Contro ...
- 第二次作业——个人项目实战(sudoku)
第二次作业--个人项目实战(sudoku) 一.作业要求地址 第二次作业--个人项目实战 二.Github项目地址 softengineering1--sudoku 三.PSP表格估计耗时 PSP2. ...
- centos 6 编译emacs-24.5
yum install `yum deplist emacs | grep provider | awk -F: '{print $2}' | awk '{print $1}' | xargs` yu ...
- js 实现路由功能
class Router { constructor() { this.routes = [] } handle(pattern, handler) { this.routes.push({ patt ...
- mysql流程控制语句
mysql编程 mysql编程中语句块包含符: 其实就是相当于js或php中大括号语法: [标识符:]begin //语句.... end [标识符]: 标识符就是定义定义的任意的名字而已,比如: ...