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语言提供的类 ...
随机推荐
- DP---(POJ1159 POJ1458 POJ1141)
POJ1159,动态规划经典题目,很适合初学者入门练手. 求:为了使字符串左右对称,应该插入的最小字符数目. 设字符串为S1 S2 S3 - Sn. 这个字符串有n个字符,根据DP的基本思路,减少问题 ...
- 设计 Azure SQL 数据库,并使用 C# 和 ADO.NET 进行连接
标题:设计 Azure SQL 数据库,并使用 C# 和 ADO.NET 进行连接 里面有使用C#使用SqlServer的例子.
- Java多线程下单例
/* 多线程下的单例 */ //饿汉式 class Single { private static final Single s = new Single(); private Single(){} ...
- Java 成员初始化顺序
package com.cwcec.test; class Fu { int num = 5; //构造代码块 { System.out.println("Fu constructor co ...
- bash 基础
bash是一些基本的命令组成,要想学好bash脚本,基本命令是必须要记住 红色标记为着重点 1执行命令,利用状态返回值来判断 0 : 成功 1-255:失败 2: 测试表达式 [ expressio ...
- 3dContactPointAnnotationTool开发日志(三一)
在玩的时候遇到了一个python的问题: Traceback (most recent call last): File ".\convert.py", line 13, in ...
- oracle 行转列和列转行
WITH L AS ( ), m AS ( SELECT A.LV AS LV_A, B.LV AS LV_B, TO_CHAR(B.LV) || 'x' || TO_CHAR(A.LV) || '= ...
- python接口自动化测试框架实现之操作oracle数据库
python操作oracle数据库需要使用到cx-oracle库. 安装:pip install cx-oracle python连接oracle数据库分以下步骤: 1.与oracle建立连接: 2. ...
- 修改Oracle redo.log文件的大小
1.查看当前日志组成员: SQL> select member from v$logfile; MEMBER ------------------------------------------ ...
- 分享几个IP获取地理位置的API接口(最全面的了)
转载;https://cloud.tencent.com/developer/article/1152362 全网首发,最全的IP接口,不服来辩!博主找了几个小时的资料,又手动抓取到了几个接口补充进来 ...