一.前言

最近部门做安卓移动开发的需要调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技术相关推荐

  1. Windows、linux环境下neo4j下载教程梳理

    Windows.linux环境下neo4j下载,无需注册 安装好java 后,要下载 neo4j ,但是官网打不开,下载不了.虽然网上那么多教程,但是小白的我试了N多命令,很多教程是关于 neo4j- ...

  2. java 调用window程序_Windows下Java调用可执行文件代码实例

    这篇文章主要介绍了Windows下Java调用可执行文件代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 缘起: 由于没有找到java转换文件 ...

  3. Java练习-----2.对Windows和Linux环境下输入的文件路径格式进行校验

    1.需求 Windows环境下路径格式只能为 D:\Desktop\source Linux环境下路径格式只能为 /data/source 2.结果展示 Linux环境下运行成功,懒得开虚拟机,就不展 ...

  4. win、linux环境下JAVA+GDAL部署,jar包启动,相关描述,问题解决

    文章目录 windows环境下JAVA+GDAL 1.GDAL下载 2.GDAL安装(既解压后拷贝) 3.GDAL测试 4.Jar包方式运行 https://www.jianshu.com/p/6bc ...

  5. 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\ ...

  6. 查看python库的版本(本质原因、Windows和Linux环境下的操作方法)

    文章目录 1. 潜在误区 2. 本质原因及正确查看方法 2.1 Linux环境下的操作方法 2.2 Windows环境下的操作方法 3. 总结 1. 潜在误区   新来的实习生又让我帮忙解决一个新问题 ...

  7. 【Nginx】Nginx在Windows、Linux环境下的下载安装详细步骤

    文章目录 Nginx下载安装 Nginx-windows安装 下载 安装 启动 Nginx-Linux安装 下载 准备 安装 启动 检查 Nginx常用命令 Nginx下载安装 Nginx跨平台,在w ...

  8. E22 SX1268 LoRa模块传输测试(定点模式)发送接收串口消息 windows与linux环境下C语言代码

    前言 近期因项目需求,对LoRa透传模块进行测试学习. 本次测试的模块是成都ebyte公司的LoRa模块,型号为SX1268.该模块采用串口透传模式. 本博客主要记录了模块的定点传输模式,透传模式相对 ...

  9. 【树莓派开发】使用树莓派在Linux环境下编写C语言代码

    文章目录 前言 1.创建test.c文件 2.编译运行该文件 3.编译并链接两个源文件 结语 前言 如何使用树莓派编译C语言代码呢? 21年暑假的时候,学习编程的劲头高涨,然后冲动消费买了个树莓派4B ...

  10. Windows和Linux环境下搭建SVN服务器

    --------------------------Windows下搭建SVN服务器----------------------------- 一.安装SVN服务端 软件包Setup-Subversi ...

最新文章

  1. 超易懂的MapReduce思想讲解
  2. hadoop常用命令之hdfs
  3. C# 网络编程之最简单浏览器实现
  4. 工作79:获取对应中文
  5. [转]Spinner的常用技巧
  6. [CLR via C#]1.6 Framework类库~1.9与非托管代码的互操作性
  7. [LeetCode] Trapping Rain Water II 题解
  8. 实习成长之路——Spring Bean 二:如何注册BeanDefinition?
  9. 简单算法系列:快速算法/冒泡算法两则
  10. 最好用的论文数据搜索网站,搜索容易让写论文变轻松!
  11. go mod invalid pseudo-version
  12. [学习SLAM]数学中的几何变换-向量叉乘/旋转轴、旋转角度和旋转矩阵/坐标系变换
  13. oracle 从后往前,oracle从后往前截取字符串 oracle截取字符串后三位
  14. Wifi-direct 相关记录
  15. 计量经济学及Stata应用 陈强 第十章工具变量法习题10.6
  16. Mybatis 学习笔记
  17. mysql配置 cloudreve_Cloudreve网盘的安装和离线下载的配置
  18. shell向文件末尾添加内容
  19. 江南百景图过Root检测
  20. php大商创商城,news.php · Mihok/ecshop大商创商城 - Gitee.com

热门文章

  1. 车联网 北斗GPS 部标平台 JT/T808
  2. 兆骑科创创业赛事活动,投融资对接,活动路演
  3. 科来网络分析系统2010v7.3.1.2436 激活注册汉化方法
  4. [源码]VB6.0操作注册表
  5. 衡量计算机主机性能的指标,计算机性能
  6. 码农小汪-Hibernate学习6-hibernate中Annocation修饰属性
  7. AIDA64内存与缓存测试过了算稳定吗_买了B460主板的你,究竟需要怎样的内存
  8. 快速导入十亿数据到hugegraph图数据库
  9. php微积分难吗,微积分中10大经典问题
  10. 刘迎东编微积分教材参考答案