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语言提供的类 ...
随机推荐
- ES6的新特性(12)——Set 和 Map 数据结构
Set 和 Map 数据结构 Set 基本用法 ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set 数据结构. co ...
- 软件工程第七周psp
1.PSP表格 类别 任务 开始时间 结束时间 中断时间 delta时间 立会 汇报昨天的成绩,分配任务,部署计划 10月27日18:00 10月27日18:36 0 36分钟 准备工作 查阅有关资料 ...
- 简评搜狗输入法(ios端)
首先说说为什么不使用iPhone自带的输入法呢,首先是词库不够丰富,好多简单的词语需要逐个字逐个字的选择,记忆功能不太好,其次是全键盘式的输入我不太习惯,还是九宫格的输入法比较简单,更方便快捷. 搜狗 ...
- HDU 5666 Segment 数论+大数
题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5666 bc(中文):http://bestcoder.hdu.edu.cn/contests ...
- css全局样式基础代码
body{ font-size:12px; font-family:"宋体",Arial, Helvetica, sans-serif;color:#363636;backgrou ...
- C语言之goto浅析
1. 读代码时遇了的疑惑点: static int do_bind(const char *host, int port, int protocol, int *family) { int fd; ...
- Windows Forms编程实战学习:第一章 初识Windows Forms
初识Windows Forms 1,用C#编程 using System.Windows.Forms; [assembly: System.Reflection.AssemblyVersion(& ...
- haproxy调度算法
调度算法详解 用balance指令指明调度算法, 例如:balance roundrobin 1:roundrobin :动态轮询算法,基于后端服务器的总权重做轮询,后端的服务器数量限制在4095 ...
- 图文详解 IntelliJ IDEA 15 创建普通 Java Web 项目
第 1 部分:新建一个 Java Web Application 项目 File -> New -> Project…,请选择 Java EE 这个模块下的 Web Application ...
- socket与TCP/UDP编程~
ket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Internet上的TCP/IP网络编程,必须理解Socket接口. ...