Java调用C++接口(初步了解)

(最近听到同事说了一下java调c++接口的事,于是就有点想了解下,然后就各种查资料记录下自己的简单实现过程,环境windows)

  • 1.有java基础的都可以啦,新建一个类,如下(很简单~)
package com.dream.mynative;

public class TestNativeHello {
    public native String getNativeHello(String words);//用native修饰要调用的其他语言的方法名
}

ps:这里我定义了一个类,类名和方法名自己取就好了,关键点就是用native取修饰你要调用的方法就好。

  • 2.接下来就需要对这个类进行编译了。(由于要生成c++能引入头文件,所以需要将这个类编译出一个 *.h 文件。这里我在编译的时候遇到了坑,查资料说再java8后,javah 这个命令被javac
    -h代替了,我这里的jdk是12的,所以当时搞了半天都没弄出结果。)

  • 2.1 找到你上面创建那个类所在的物理路径位置,进入,然后执行cmd,如下: 在这里插入图片描述

    进入到类所在文件目录执行以上命令即可(注意jdk版本) 执行成功后,会在你类的目录中生成.h文件。如下:
    在这里插入图片描述

    同时还生成了.class文件,这里我们只用到这个.h文件

  • 2.2准备好.h头文件后,接下来我们就需要写c++代码去实现这个方法了(代码很基础的,不懂的可以网上查查。我这里用的是vs2013编译器写的)

  • 2.2.1新建一个控制台应用程序,如下:

在这里插入图片描述

名字自己定义就好

  • 2.2.2 接下来,注意选择dll,如下:

在这里插入图片描述

  • 2.2.3 然后需要导入几个.h文件和之前编译出来的.h文件到工程的头文件中。列表如下:

在这里插入图片描述

这里需要注意的点是:1:其它几个文件可以在你的jdk中找到。2:要将你自己生成的那个.h文件中对jin.h的进入方式改一下,改成引号方式引入,如下:

在这里插入图片描述

  • 2.2.4 好了,以上工作做好了后就可开始写C++代码了,如下:
#include "com_dream_mynative_TestNativeHello.h"
#include "stdio.h"
#include <string>
using namespace std;

std::string jstring2str(JNIEnv* env, jstring jstr);
jstring str2jstring(JNIEnv* env, const char* pat);

//此处是对方法的实现,定义和名称等信息可以从之前的.h文件中拷贝过来
//我这里简单的实现了一个对字符串的拼接 返回
JNIEXPORT jstring JNICALL Java_com_dream_mynative_TestNativeHello_getNativeHello
(JNIEnv * j, jobject, jstring s){
	
	string s1 = "hello world";
	string s2 = jstring2str(j,s);
	s1.append(s2);
	return str2jstring(j,s1.c_str()) ;
}

//此处是string 转jstring 网上有方法
jstring str2jstring(JNIEnv* env, const char* pat)
{
	
	//定义java String类 strClass
	jclass strClass = (env)->FindClass("Ljava/lang/String;");
	//获取String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
	jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
	//建立byte数组
	jbyteArray bytes = (env)->NewByteArray(strlen(pat));
	//将char* 转换为byte数组
	(env)->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
	// 设置String, 保存语言类型,用于byte数组转换至String时的参数
	jstring encoding = (env)->NewStringUTF("GB2312");
	//将byte数组转换为java String,并输出
	return (jstring)(env)->NewObject(strClass, ctorID, bytes, encoding);
}
//此处是jstring 转string 网上有方法
std::string jstring2str(JNIEnv* env, jstring jstr)
{
	char*   rtn = NULL;
	jclass   clsstring = env->FindClass("java/lang/String");
	jstring   strencode = env->NewStringUTF("GB2312");
	jmethodID   mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
	jbyteArray   barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
	jsize   alen = env->GetArrayLength(barr);
	jbyte*   ba = env->GetByteArrayElements(barr, JNI_FALSE);
	if (alen   >   0)
	{
		rtn = (char*)malloc(alen + 1);
		memcpy(rtn, ba, alen);
		rtn[alen] = 0;
	}
	env->ReleaseByteArrayElements(barr, ba, 0);
	std::string stemp(rtn);
	free(rtn);
	return   stemp;
}

写好后,就可以编译生成dll文件了。(代码很简单,就是对字符串拼接后返回,只有几行。其他两个方法主要是用来对string 和jstring进行转换用的。可以网上找到。)dll文件(动态链接库)位置在 你所建项目的Debug目录下。如下:

在这里插入图片描述

  • 3.接下来就是将这个dll文件添加到你的java工程依赖库中了。这个就不再细说,怎么添加其他依赖的就怎么添加这个dll就好了。
  • 4.最后就是对这个native方法进行调用、测试了。由于我是在之前一个spring项目中写的,所以这里就直接在spring的test中取测试、验证了。如下:(可以直接单独写一个main方法去验证)
 @Test
    public void test3(){
        System.loadLibrary("TestNativeHello");//要先加载这个动态链接库,名字就是生成的dll名
        TestNativeHello hello = new TestNativeHello();//new对象
        String res =  hello.getNativeHello("hahah");//调用native方法
        System.out.println(res);
    }

打印结果如下:
在这里插入图片描述

此时,就已经完成简单的对c++接口调用啦,over…over!!!

---------------------------初步学习,共同进步-----------------------

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值