windows和linux环境下java调用C++代码-JNI技术
一.前言
最近部门做安卓移动开发的需要调C++的代码,困难重重,最后任务交给了我,查找相关资料,没有一个教程能把不同环境(windows,linux)下怎么调用说明白的,自己在实现的过程中踩了几个坑,在这里总结下,希望看到的以后能少走弯路。
使用工具:
1.JAVA使用的IDE为eclipse
2.windows环境下C++使用的IDE为visual studio 2010
3.linux环境下C++使用的编译器为gcc/g++
二.windows环境下java调用C++代码
2.1新建java工程,生成相应头文件
eclipse新建工程名为"jniDemo"的java工程,在包名为com.woniu.Native下新建"NativeCpp.java"类,如下:
package com.woniu.Native;public class NativeCpp {public native void fun1();public native int fun2(int a, int b);public native void fun3(String url1, String url2);
}
编译生成.class文件
进入工程下的target\classes目录下,执行"javah -jni com.woniu.Native.NativeCpp",运行结果如下:
此时,会在classes目录下生成"com_woniu_Native_NativeCpp.h"头文件,头文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_woniu_Native_NativeCpp */#ifndef _Included_com_woniu_Native_NativeCpp
#define _Included_com_woniu_Native_NativeCpp
#ifdef __cplusplus
extern "C" {
#endif
/** Class: com_woniu_Native_NativeCpp* Method: fun1* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_woniu_Native_NativeCpp_fun1(JNIEnv *, jobject);/** Class: com_woniu_Native_NativeCpp* Method: fun2* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_woniu_Native_NativeCpp_fun2(JNIEnv *, jobject, jint, jint);/** Class: com_woniu_Native_NativeCpp* Method: fun3* Signature: (Ljava/lang/String;Ljava/lang/String;)V*/
JNIEXPORT void JNICALL Java_com_woniu_Native_NativeCpp_fun3(JNIEnv *, jobject, jstring, jstring);#ifdef __cplusplus
}
#endif
#endif
2.2 c++生成动态库
vs2010新建工程名为"JniDll"的win32控制台应用程序,win32应用程序向导界面选择 "DLL"
创建完成后,把2.1中生成的"com_woniu_Native_NativeCpp.h"头文件放入该工程,并把头文件中的#include <jni.h>改为 "jni.h",
把JDK下include文件夹下的"jni.h"和include下win32文件夹下的"jni_md.h"头文件也一同放入创建的工程中。
工程目录如下:
编辑JniDll.cpp源码文件,实现头文件中的函数,如下:
/********************************************************
Copyright (C), 2016-2017,
FileName: jni
Author: woniu201
Email: wangpengfei.201@163.com
Created: 2017/09/20
Description:Jni function
********************************************************/
#include "stdafx.h"
#include "com_woniu_Native_NativeCpp.h"
#include "stdio.h"
#include "stdlib.h"JNIEXPORT void JNICALL Java_com_woniu_Native_NativeCpp_fun1(JNIEnv *, jobject)
{printf("hello world\n");
}JNIEXPORT jint JNICALL Java_com_woniu_Native_NativeCpp_fun2(JNIEnv *, jobject, jint a, jint b)
{return a + b;
}char* jstringToChar(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);return rtn;
}JNIEXPORT void JNICALL Java_com_woniu_Native_NativeCpp_fun3(JNIEnv *env, jobject, jstring url1, jstring url2)
{//jstringתchar*char* pUrl1 = jstringToChar(env, url1);char* pUrl2 = jstringToChar(env, url2);printf("url1 = %s\n", pUrl1);printf("url2 = %s\n", pUrl2);
}
我本机是64位系统,使用的是64位JDK,这里生成的动态库也要生成64位的库,否则调用的时候报如下错误:
更改vs编译生成64位dll,步骤如下:
编译生成解决方案,这时候会在工程根目录下,生成"x64文件夹",Debug文件夹下会有动态库"JniDll.dll"
2.3 java调用dll
package com.woniu.jniDemo;import com.woniu.Native.NativeCpp;public class App
{public static void main( String[] args ){System.load("D:\\VS2010\\VC\\JniDll\\x64\\Debug\\JniDll.dll");NativeCpp nativeCpp = new NativeCpp();nativeCpp.fun1();System.out.println(nativeCpp.fun2(3, 3));nativeCpp.fun3("www.baidu.com", "www.haoservice.cn");}
}
运行结果如下:
三.linux(CentOS)环境下java调用C++代码
3.1 编译环境
a.安装gcc和g++
yum install gcc-c++
b.安装jdk
去官网上下载jdk安装包,建议使用rpm安装包,会自动配置环境变量。安装完后如下:
本机的安装目录为:/usr/java/jdk1.8.0_144/,不同版本可能不同。
这里一定要注意不能安装openjdk,因为openjdk没有include目录,编译时需要用到include目录的头文件。
3.2 制作动态库(so库)
a.创建文件夹"jniso",mkdir jniso。
b.把2.1中生成的头文件"com_woniu_Native_NativeCpp.h"拷贝过来,#include "jni.h"改为#include <jni.h>
c.新建jni.cpp源文件,添加如下代码:
#include <jni.h>
#include "com_woniu_Native_NativeCpp.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"JNIEXPORT void JNICALL Java_com_woniu_Native_NativeCpp_fun1 (JNIEnv *, jobject)
{printf("hello world\n");
}JNIEXPORT jint JNICALL Java_com_woniu_Native_NativeCpp_fun2(JNIEnv *, jobject, jint a, jint b)
{return a + b;
}char* jstringToChar(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);return rtn;
}JNIEXPORT void JNICALL Java_com_woniu_Native_NativeCpp_fun3(JNIEnv *env, jobject, jstring url1, jstring url2)
{char* pUrl1 = jstringToChar(env, url1);char* pUrl2 = jstringToChar(env, url2);printf("url1 = %s\n", pUrl1);printf("url2 = %s\n", pUrl2);
}
d.编译,生成动态库
g++ -fPIC -c jni.cpp -I /usr/java/jdk1.8.0_144/include/ -I /usr/java/jdk1.8.0_144/include/linux/
g++ -shared jni.o -o jni.so
3.3 java调用jni.so
import com.woniu.Native.NativeCpp;public class App
{public static void main( String[] args ){//windows环境下加载库//System.load("D:\\VS2010\\VC\\JniDll\\x64\\Debug\\JniDll.dll");//linux下加载库System.load("/mnt/hgfs/svn/svn/Demo/jniso/jni.so");NativeCpp nativeCpp = new NativeCpp();nativeCpp.fun1();System.out.println(nativeCpp.fun2(3, 3));nativeCpp.fun3("www.baidu.com", "www.haoservice.cn");}
}
运行结果如下:
windows下生成dll源码地址:点击打开链接
没有下载积分的,可以关注下面公众号,回复"105"获取源码
linux下生成so动态库源码地址:点击打开链接
没有下载积分的,可以关注下面公众号,回复"106"获取源码
windows和linux环境下java调用C++代码-JNI技术相关推荐
- Windows、linux环境下neo4j下载教程梳理
Windows.linux环境下neo4j下载,无需注册 安装好java 后,要下载 neo4j ,但是官网打不开,下载不了.虽然网上那么多教程,但是小白的我试了N多命令,很多教程是关于 neo4j- ...
- java 调用window程序_Windows下Java调用可执行文件代码实例
这篇文章主要介绍了Windows下Java调用可执行文件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 缘起: 由于没有找到java转换文件 ...
- Java练习-----2.对Windows和Linux环境下输入的文件路径格式进行校验
1.需求 Windows环境下路径格式只能为 D:\Desktop\source Linux环境下路径格式只能为 /data/source 2.结果展示 Linux环境下运行成功,懒得开虚拟机,就不展 ...
- win、linux环境下JAVA+GDAL部署,jar包启动,相关描述,问题解决
文章目录 windows环境下JAVA+GDAL 1.GDAL下载 2.GDAL安装(既解压后拷贝) 3.GDAL测试 4.Jar包方式运行 https://www.jianshu.com/p/6bc ...
- r语言和metawin_如何创建R的HelloWorld包(Windows或Linux环境下)
1.Windows环境下 1.2安装完后,配置系统的path 1.2.1假定R的安装路径在:D:\Program Files\R\R-2.5.0\bin:Rtools的安装路径在:c:\Rtools\ ...
- 查看python库的版本(本质原因、Windows和Linux环境下的操作方法)
文章目录 1. 潜在误区 2. 本质原因及正确查看方法 2.1 Linux环境下的操作方法 2.2 Windows环境下的操作方法 3. 总结 1. 潜在误区 新来的实习生又让我帮忙解决一个新问题 ...
- 【Nginx】Nginx在Windows、Linux环境下的下载安装详细步骤
文章目录 Nginx下载安装 Nginx-windows安装 下载 安装 启动 Nginx-Linux安装 下载 准备 安装 启动 检查 Nginx常用命令 Nginx下载安装 Nginx跨平台,在w ...
- E22 SX1268 LoRa模块传输测试(定点模式)发送接收串口消息 windows与linux环境下C语言代码
前言 近期因项目需求,对LoRa透传模块进行测试学习. 本次测试的模块是成都ebyte公司的LoRa模块,型号为SX1268.该模块采用串口透传模式. 本博客主要记录了模块的定点传输模式,透传模式相对 ...
- 【树莓派开发】使用树莓派在Linux环境下编写C语言代码
文章目录 前言 1.创建test.c文件 2.编译运行该文件 3.编译并链接两个源文件 结语 前言 如何使用树莓派编译C语言代码呢? 21年暑假的时候,学习编程的劲头高涨,然后冲动消费买了个树莓派4B ...
- Windows和Linux环境下搭建SVN服务器
--------------------------Windows下搭建SVN服务器----------------------------- 一.安装SVN服务端 软件包Setup-Subversi ...
最新文章
- 超易懂的MapReduce思想讲解
- hadoop常用命令之hdfs
- C# 网络编程之最简单浏览器实现
- 工作79:获取对应中文
- [转]Spinner的常用技巧
- [CLR via C#]1.6 Framework类库~1.9与非托管代码的互操作性
- [LeetCode] Trapping Rain Water II 题解
- 实习成长之路——Spring Bean 二:如何注册BeanDefinition?
- 简单算法系列:快速算法/冒泡算法两则
- 最好用的论文数据搜索网站,搜索容易让写论文变轻松!
- go mod invalid pseudo-version
- [学习SLAM]数学中的几何变换-向量叉乘/旋转轴、旋转角度和旋转矩阵/坐标系变换
- oracle 从后往前,oracle从后往前截取字符串 oracle截取字符串后三位
- Wifi-direct 相关记录
- 计量经济学及Stata应用 陈强 第十章工具变量法习题10.6
- Mybatis 学习笔记
- mysql配置 cloudreve_Cloudreve网盘的安装和离线下载的配置
- shell向文件末尾添加内容
- 江南百景图过Root检测
- php大商创商城,news.php · Mihok/ecshop大商创商城 - Gitee.com
热门文章
- 车联网 北斗GPS 部标平台 JT/T808
- 兆骑科创创业赛事活动,投融资对接,活动路演
- 科来网络分析系统2010v7.3.1.2436 激活注册汉化方法
- [源码]VB6.0操作注册表
- 衡量计算机主机性能的指标,计算机性能
- 码农小汪-Hibernate学习6-hibernate中Annocation修饰属性
- AIDA64内存与缓存测试过了算稳定吗_买了B460主板的你,究竟需要怎样的内存
- 快速导入十亿数据到hugegraph图数据库
- php微积分难吗,微积分中10大经典问题
- 刘迎东编微积分教材参考答案