Win10下配置JNI,Java与C++沟通的桥梁

1 篇文章 0 订阅

JNI是Java用来与C++之类的语言交互的一个工具,非常好用,配置不难。因为有时候一些函数是用c++库写的,没有Java版本,所以要使用很麻烦,但是如果Java可以调用C++的dll或者lib,那么就会很方便,JNI就是这样一种工具。下面介绍通俗易懂的配置方法:

Java代码——

首先,在Java里新建的类中写下需要被调用的C++函数,关键字是native,如图

GetJsonDwg是C++里实现的函数,这里需要被java调用,传送一个String类型的参数,返回一个String类型的结果。另外,需要些引用的路径,如图

TestJNI是dll或者lib的名称,也就是C++的工程名。

使用的时候就这样写,如图

这里的TestJNI表示的Java中类的名称(注意与上面的TestJNI表示的不是一个东西),我碰巧设成一样的了。hw.GetJsonDwg()就是应用了C++的方法。到此,Java部分代码就完成了。

cmd操作——

接下来需要对这个.java文件编译成C++可以引用的.h文件,我们可以在cmd中很容易地完成。首先在cmd中切换到Java工程的bin目录下,即.h所在的目录(用cd命令),如图

然后输入以下命令,如图:

这句话的意思是将编译的.h文件生成在当前路径中,头文件名是com_testjni_TestJNI,这个名称不是随便起的,com_testjni是Java类所在的包名,TestJNI是C++的库名。

这部执行完后,在bin目录下会生成一个 com_testjni_TestJNI.h的头文件,这就是上面命令行执行的结果。

C++部分——

接下来转到C++部分,我们创建一个Win32控制台应用程序,配置如图

我们给项目设置属性,C/C++--常规--附加包含目录,添加Java目录下的jni.h和jni_md.h所在的路径,我的电脑下的路径如图

一般位置基本一样,反正只要找到Java的目录,后面部分都是在include里找。

然后将之前编译的头文件com_testjni_TestJNI.h放到C++的工程目录下,就是放到和.cpp这些文件的同一个目录中,然后右键头文件--添加--现有项,将这个头文件引用进来。如果头文件有问题,就把#include  <jni.h>改为#include "jni.h",反正我是不用改就可以用。

接下来创建一个.cpp,然后在里面写刚刚那个需要的函数,就是GetJsonDwg(),写法如下:

JNIEXPORT jstring JNICALL Java_com_testjni_TestJNI_GetJsonDwg
(JNIEnv *env, jobject obj, jstring filepath){
jstring file = filepath;
jstring a = env->NewStringUTF("LiYu");
return a;
}

红色部分jstring对应Java中的String,绿色部分Java_com_testjni_TestJNI_GetJsonDwg的命名规则是:Java_工程名_函数名,黄色部分是默认的参数,自带,后面的jstring filepath就是传递的参数。以上仅是简单示例,重在告知原理,具体函数内容根据需求来实现。另外这个函数的写法可以到.h文件中去复制就行了!只不过自己要把出传递的参数添加一个具体的名称。

写好后右键项目--生成,然后在工程目录Debug中,我们就可以找到生成的.dll和.lib了。

配置Java Build Path——

右键包--Build Path--Configure Build Path,点击Libraries--JRE System Library--Native library location,点击Edit,把上面的.dll和.lib所在的路径添加进去,Apply and Close。如图

这个步骤是将库引用进来,这样代码中的System.loadLibrary("TestJNI");才能找到对应的库。

这样配置就完成了。

最后运行main函数,应该是可以正常调用C++的库中的函数了,如图

总结——

总结来说,JNI应该是一个不错的原生的接口,可以解决部分库缺乏Java版本的问题。不同的语言之间的交互确实是一个问题,这也包括传输的编码问题。这篇的文章没有深究传输编码问题,实际上如果C++直接返回一个中文字符串时会存在乱码的问题的,因为C++里是gbk编码,需要先转化为utf8/16才行,附代码如下:

//传递中文字符串,gb2312转utf8/16
jstring charTojstring(JNIEnv* env, char* str)
{
	jstring rtn = 0;
	int slen = strlen(str);
	unsigned short * buffer = 0;
	if (slen == 0)
		rtn = (env)->NewStringUTF(str);
	else
	{
		int length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, slen, NULL, 0);
		buffer = (unsigned short *)malloc(length * 2 + 1);
		if (MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length) > 0)
			rtn = (env)->NewString((jchar*)buffer, length);
	}
	if (buffer)
		free(buffer);
	return rtn;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HouGISer

HouGiser需要你的鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值