C++回调函数调用Java接口抽象函数
来源:互联网 发布:如何系统地自学python 编辑:程序博客网 时间:2024/06/05 06:02
项目中很多代码采用C++编写,配置界面则采用BS结构,使用Java语言进行设置。因此需要实现Java调用C++编写的函数库(dll文件或so文件),采用的技术为JNI(Java Native Interface),对于常用的调用方式在《The Java Native Interface Programmer's Guide and Specification》一书中有详细的描述,不在进行描述。本文中主要介绍在动态链接库中如果含有回调函数作为函数参数的C++函数如何使用JNI实现调用。在C++中函数定义格式为:
typedef int (*UserProcess)(int nEncrptType);
CALLBACK_API int Process(UserProcess cb,int nCompanID);
即如何采用Java语言实现Process函数?下面将分别针对C++和Java语言使用回调函数进行说明。
1.回调函数库
本文中定义了一个简单的回调函数接口,目的是根据公司ID进行加密,加密函数为回调函数。头文件定义如下
#ifdef CALLBACK_EXPORTS#define CALLBACK_API __declspec(dllexport)#else#define CALLBACK_API __declspec(dllimport)#endif#ifdef __cplusplusextern "C"{#endif typedef int (*UserProcess)(int nEncrptType); CALLBACK_API int Process(UserProcess cb,int nCompanID);#ifdef __cplusplus}#endif
其实现文件为
#include "stdafx.h"#include "CallBack.h"CALLBACK_API int Process(UserProcess cb,int nCompanID){ if(cb == NULL) { return -1; } cb(nCompanID); return 0;}2.C++语言使用回调函数库
用法比较简单,直接实现一个满足UserProcess定义的函数,然后将其传递给Process函数即可,见下文代码内容。
#include "stdafx.h"#include "../CallBack/CallBack.h"int WanporProcess(int i){ printf("Process = %d\n",i); return i;}int _tmain(int argc, _TCHAR* argv[]){ Process(WanporProcess,100); return 0;}
加密函数将公司ID直接输出,未进行其他处理。
3.Java语言使用回调函数
这个过程相对于C++显得比较繁琐,主要包含以下一个过程:
3.1编写回调函数的抽象接口,并实现一个回调类;
3.2在JNI中安装回调接口类
3.3实现C++的回调函数,在此回调函数中获取抽象接口类对象、回调函数的接口名称、调用回调函数
3.4调用process进行回调函数执行
2.5卸载回调类
下面依次实现上述中的内容
3.1回调函数接口定义
package cn.com.wanpor;//编写回调函数接口public interface CBInterface{ public abstract int UserProcess(int encryptType);}
3.2实现回调类
//实现回调类class WanporCB implements CBInterface { public int UserProcess(int encryptType){ System.out.println("Java = " + 3*encryptType); return 0; }}
3.3C++ JNI代码中安装回调类
#include "stdafx.h"#include "../CallBack/CallBack.h"#include "cn_com_wanpor_CallBackJNI.h"typedef struct CBData{ UserProcess m_pfnUserProcess; jobject m_objInterface; JNIEnv* m_pEnv; jobject m_objCallBack;}CBData;CBData g_cbData;JNIEXPORT jint JNICALL Java_cn_com_wanpor_CallBackJNI_setUserCallBack(JNIEnv * env, jobject obj, jobject cb){ g_cbData.m_pEnv = env; g_cbData.m_objCallBack = env->NewGlobalRef(obj); g_cbData.m_objInterface = env->NewGlobalRef(cb); return 0;}
3.4实现C++回调函数
int ProcessJNICB(int nEncrpytType){ JavaVM* pVm; g_cbData.m_pEnv->GetJavaVM(&pVm); pVm->AttachCurrentThread((void**)&g_cbData.m_pEnv,NULL); jclass jclsProcess = g_cbData.m_pEnv->GetObjectClass(g_cbData.m_objInterface); if (jclsProcess == NULL) { printf("jclsProcess = NULL\n"); return -1; } jmethodID jmidProcess = g_cbData.m_pEnv->GetMethodID(jclsProcess,"UserProcess","(I)I"); if (jmidProcess == NULL) { printf("jmidProcess = NULL\n"); return -2; } g_cbData.m_pEnv->CallIntMethod(g_cbData.m_objInterface,jmidProcess,nEncrpytType); pVm->DetachCurrentThread(); return 0;}
3.5执行回调函数
JNIEXPORT jint JNICALL Java_cn_com_wanpor_CallBackJNI_process(JNIEnv * env, jobject obj, jint nCompanyID){ Process(ProcessJNICB,nCompanyID); return 0;}
3.6卸载回调类
JNIEXPORT jint JNICALL Java_cn_com_wanpor_CallBackJNI_resetUserCallBack(JNIEnv * env, jobject objCallBack, jobject objInterface){ g_cbData.m_pEnv->DeleteGlobalRef(objInterface); g_cbData.m_pEnv->DeleteGlobalRef(objCallBack); return 0;}
4.Java测试程序
下面的代码是对JNI接口的测试程序,WanporCB实现了回调接口,回调函数返回值为0,但打印出3*nCompany的值,程序执行函数的顺序是:
创建回调函数接口实例
创建测试对象
安装回调类
执行加密
卸载回调类
代码如下:
package cn.com.wanpor;//实现回调类class WanporCB implements CBInterface { public int UserProcess(int encryptType){ System.out.println("Java = " + 3*encryptType); return 0; }}public class CallBackJNI{ static{ System.load("E:\\Program Files\\Java\\jdk1.5.0_15\\bin\\CallBackJNI.dll"); } //设置回调函数 public native int setUserCallBack(CBInterface cb); //清除回调函数 public native int resetUserCallBack(CBInterface cb); //执行用户自定义加密 public native int process(int companyID); //测试程序 public static void main(String[] argv){ CallBackJNI cbj = new CallBackJNI(); WanporCB wcb = new WanporCB(); cbj.setUserCallBack(wcb); cbj.process(300); cbj.resetUserCallBack(wcb); } }
0 0
- C++回调函数调用Java接口抽象函数
- C++回调函数调用Java接口抽象函数
- C++回调函数调用Java接口抽象函数
- C++回调函数调用Java接口抽象函数
- c的回调函数与java中抽象函数,接口函数,抽象类简单理解
- c#调用c++dll接口及回调函数
- Java/Android中的函数调用&回调函数&自定义回调函数
- Java/Android中的函数调用&回调函数&自定义回调函数
- Java/Android中的函数调用&回调函数&自定义回调函数
- Java/Android中的函数调用&回调函数&自定义回调函数
- Java/Android中的函数调用&回调函数&自定义回调函数
- Java调用C语言Dll库回调函数
- 4.8 抽象接口, 回调函数: 短信备份
- 函数调用习惯与回调函数
- 关于回调函数和函数调用
- C# 调用C/C++回调函数
- c风格回调函数 vs c++风格虚基类,关于接口定义和调用的对比
- Java回调函数之callback接口
- C++风格的字符串string类
- 柯震东吸毒道歉有用么!!!
- C#中的线程(一)入门
- php版本的cron定时任务执行器使用实例
- HoneyDrive 到底是个什么玩意
- C++回调函数调用Java接口抽象函数
- ios播放音乐(短音乐,长音乐)
- 3Sum Closest Java
- hdu 2054
- Android手势监听类GestureDetector的使用
- Hive安装好之后创建表时报错MySQLSyntaxErrorException: Specified key was too long; max key length is 767 bytes
- struts2的execAndWait拦截器使用
- 用指针玩字符串--字符串长度
- 防撞扶手做出的巨大贡献