用C++调用jar包以及一些注意事项

用C++调用jar包以及一些注意事项

1.打出一个漂亮的jar包

(1)我创建的java工程目录:
工程目录
(2)编写JAVA代码
此处我写了三个函数,main()、add()、toUppercase()


package com.yxyhard.test;

public class Test {

    public static void main(String[] args) {

        Test test = new Test();

        // test add
        System.out.printf("1 + 2 = %d\n", test.add(1, 2));

        // test toUpperCase
        String greeting = "hello, world!";
        System.out.printf("Upper case of \"%s\" is \"%s\"\n",
                greeting, test.toUpperCase(greeting));
    }

    public int add(int num1, int num2) {
        return num1 + num2;
    }

    public String toUpperCase(String str) {
        return str.toUpperCase();
    }
}

(3)直接在java中打jar包
file-Project Strcture
打jar包
点击artifacts , +,填入要保存的路径,点击OK,则可在设置的路径下成功创建一个jar包
生成jar包
生成的jar包

(4)验证jar包是否生成成功
在jar包路径下打开cmd,输入命令java -jar JINTest.jar,如果cmd窗口出现所写代码的输出内容,则说明生成jar包成功
在这里插入图片描述

2.C++调用jar包

(1)首先准备需要用到的Jdk中的文件:jin.h、jin_md.h、JVM.dll
路径分别为:D:\Java\jdk1.8.0_261\include\jin.h
D:\Java\jdk1.8.0_261\include\win32\jin_md.h
D:\Java\jdk1.8.0_261\jre\bin\server\JVM.dll
我不成熟的做法是将两个.h文件copy到我的C++头文件下,直接在主函数中include调用
(2)编写C++代码,调用jar包

#include "jni.h"
#include <Windows.h>
#include<iostream>
using namespace std;
int main()
{

		/* 设置 JVM 参数 */
		JavaVMInitArgs vmArgs;
		vmArgs.version = JNI_VERSION_1_8;\

		const int OPTION_COUNT = 2;
		vmArgs.nOptions = OPTION_COUNT;
		JavaVMOption options[OPTION_COUNT] = { 0 };
		// classpath 指定为我们要调用的 jar 包路径
		//options[0].optionString = "-Djava.class.path=G:\\projects\\java\\JNITest\\test.jar";
		  options[0].optionString = "-Djava.class.path=D:\\JINTest\\JINTest.jar";
		options[1].optionString = "-Xmx1024m";  // 最大堆大小
		vmArgs.options = options;
		vmArgs.ignoreUnrecognized = JNI_TRUE;

		/* 启动 JVM */
		//HMODULE hModule = LoadLibrary(TEXT("G:\\Java\\jre1.8.0_131\\bin\\server\\jvm.dll"));//加载jvm库
	   //D:\Java\jdk1.8.0_261\jre\bin\server   D:\Java\pre\bin\server
		HMODULE hModule = LoadLibrary(TEXT("D:\\Java\\pre\\bin\\server\\jvm.dll"));
	
		if (hModule == NULL)
		{
			cout << "LoadLibrary False" << endl;
			return -1;
		}
		typedef jint(JNICALL *CreateJavaVMFuncPtr)(JavaVM **pvm, void **penv, void *args);
		CreateJavaVMFuncPtr CreateJavaVM = (CreateJavaVMFuncPtr)GetProcAddress(hModule, "JNI_CreateJavaVM");
		JavaVM *jvm = nullptr;
		JNIEnv *env = nullptr;
		jint res = (*CreateJavaVM)(&jvm, (void**)&env, &vmArgs);
		if (res < 0)
		{
			return -1;
		}

		/* 调用 class */
		// 找到 class
		//jclass class_Test = env->FindClass("com/cynhard/test/Test");
		jclass class_Test = env->FindClass("com/yxyhard/test/Test");
	
		jmethodID methodId_main = env->GetStaticMethodID(class_Test, "main", "([Ljava/lang/String;)V");
		env->CallStaticVoidMethod(class_Test, methodId_main, "");

		// 释放资源
		jvm->DestroyJavaVM();

		FreeLibrary(hModule);

		return 0;
	
}

3.一些注意事项:

(1)编译C++代码时JVM.dll文件调用失败
解决方法:
可能是平台和dll文件之间不兼容,于是将"解决方案平台"改为X64(如下图)

jiang将图中的X86改为X64
(2)代码中GetStaticMethodID的参数不确定
在这里插入图片描述

解决办法:
打开cmd,cd到java工程目录下,如果没有class文件,则用 javac Test.java 生成class文件,再输入javap -s Test.class ,即可得到结果(如下图)。每个函数有对应的参数,我的代码对应的main函数,因此用main函数对应的参数([Ljava/lang/String;)V
在这里插入图片描述
以上就是所有的C++通过JIN调用jar包的过程,记录一下,供以后参考。
参考文档:https://blog.csdn.net/u011304970/article/details/75713209?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.controls

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值