jni编程 C++调用java详解


前言

前段时间公司因项目需要,需要使用C++调用jar包,但是网上的资料零零散散,完整的可借鉴的开发资料少之又少,于是就有了这篇文章, 把这段时间的开发的经验总结一下,以后,自己也可以回过头来温习一下,各位读者如果对调用流程不是很熟悉,只要细心的阅读,相信一定会有收获的。


一、说明

C++调用java的是通过加载java虚拟机来解释java字节码,然后再通过虚拟机来调用对应的java代码,
首先加载jvm库,只要安装了JDK都会有jvm库(动态库和静态库都有),加载流程如下
本文以动态库为实例

二、使用步骤

1.加载jvm动态库

代码如下(示例):

char szJVMpath[MAX_PATH] = {
   0};

//通过环境变量javahome直接获取jvm.dll的路径,这里说明一下这个路径可以自己设置,不一定非要使用已经安装的jdk。
sprintf(szJVMpath, "%s\\jre\\bin\\server\\jvm.dll", getenv("JAVA_HOME"));

HINSTANCE hInstance = LoadLibrary(szJVMpath);
	if (hInstance == NULL)
	{
   
		return false;
	}

	pFnCreateJavaVM m_CreateJavaVM = (pFnCreateJavaVM)GetProcAddress(hInstance, "JNI_CreateJavaVM");

	pFnGetCreatedJavaVMs m_GetCreatedJavaVMs = (pFnGetCreatedJavaVMs)GetProcAddress(hInstance, "JNI_GetCreatedJavaVMs");

	if (NULL == m_CreateJavaVM || NULL == m_GetCreatedJavaVMs)
	{
   
		return false;
	}
		

2.创建虚拟机

代码如下(示例):


	int ret = 0;

	JavaVM* Tempjvm = NULL;
	jsize count;
	
/*先获取当前进程中是否有已存在的jvm虚拟机, 如果存在则直接获取该虚拟机句柄, 如果不存在则创建新的虚拟机,

 因为较新的jdk中一个进程中只允许存在创建一个虚拟机,如果当前进程中已存在虚拟机,重新调用m_CreateJavaVM接口创建虚拟机会失败。

如果你需要多线程使用虚拟机,则需要考虑这种情况, 因为虚拟机中  JavaVM虚拟机句柄是线程共享的    环境上下文env是非线程共享的
*/
	ret = m_GetCreatedJavaVMs(&Tempjvm, sizeof(JavaVM) * 10, &count);
	
	JNIEnv* env;
	JavaVM* jvm;

		
	if (0 == ret  &&  NULL != Tempjvm && count > 0)
	{
   
		jvm = Tempjvm;
	}
	else
	{
   
		JavaVMInitArgs vm_args;
		const int OPTION_COUNT = 5;
		vm_args.nOptions = OPTION_COUNT;
		JavaVMOption options[OPTION_COUNT] = {
    0 };
	
		char Currpath[256] = {
   0};
		int nCurrpathlen = 255;
		getcwd(Currpath, nCurrpathlen);
	
		char JarPath[256] = {
   0};
		char optionStringBuffer[1024] = {
   0};
	
		strcpy(JarPath, Currpath);
		strcat(JarPath, "\\icbc-api-sdk-cop.zip");
	
		char JarPath_io[256] = {
   0};
		strcpy(JarPath_io, Currpath);
		strcat(JarPath_io, "\\icbc-api-sdk-cop-io.zip");
	
		char JarPath_hsm[256] = {
   0};
		strcpy(JarPath_hsm, Currpath);
		strcat(JarPath_hsm, "\\hsm-software-share-1.0.3.jar");

		sprintf(optionStringBuffer, "-Djava.class.path=%s;%s;%s", JarPath, JarPath_io, JarPath_hsm);
	
		//这里是设置需要加载的java文件,或者jar包,不同的源文件用;隔开即可。
		options[0].optionString = optionStringBuffer;
	
		/*这里是设置虚拟机的内存空间大小,vm虚拟机的内存 主要由三块构成(年轻代+老年代+持久代)
		年轻代:所有新生成的对象都是放在年轻代中,年轻代的目的就是快速回收那些短生命周期的对象,年轻代分三个区,一个Edge区, 两个Survivor区域,大部分对象在Edge区生成,
	当Edge区满了之后,虚拟机会将触发Scavenge GC,将edge还存活的对象移到Survivor区(两个其中的一个),当这个Survivor区满时
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值