专栏首页流媒体Jni教程(一)—Linux下jni调用简介

Jni教程(一)—Linux下jni调用简介

简介

  • 开发环境
  • 代码结构
  • .h文件生成
  • 编译生成so文件
  • 运行
  • 扩展(有包名的情况)

开发环境

  • centos 6.8 ×64
[root@localhost jni]# cat /proc/version 
Linux version 2.6.32-696.10.2.el6.x86_64 (mockbuild@c1bl.rdu2.centos.org) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) ) #1 SMP Tue Sep 12 14:33:29 UTC 2017
  • jdk 1.8 目录 /usr/local/java/jdk1.8.0_144
[root@localhost jni]# java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
  • g++ 4.4.7
[root@localhost jdk1.8.0_144]# g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
Copyright © 2010 Free Software Foundation, Inc.
本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保;
包括没有适销性和某一专用目的下的适用性担保。

代码结构

为了方便大家能够快速入门,先写一个简单的示例来演示。 先看下代码结构:

1.png

  • JavaMain.java java源代码
  • CppLib.cpp C++源代码
  • JavaMain.h 是由JavaMain.java生成的头文件

.h文件生成

public class JavaMain{
  public static void main(String[] args){
    System.out.println("Ok!");
    new JavaMain().show();
  }

  public native void show();
  static{
    System.loadLibrary("cpp");
  }
}

代码很简单,native来声明该方法非java方法。static代码块来加载动态库。

接下来就是生成.h文件。直接执行

javah JavaMain.java

生成JavaMain.h头文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JavaMain */

#ifndef _Included_JavaMain
#define _Included_JavaMain
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JavaMain
 * Method:    show
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JavaMain_show
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

编译生成so文件

接下来就是引入头文件进行C/C++编码。

#include "JavaMain.h"
#include "jni.h"
JNIEXPORT void JNICALL Java_JavaMain_show
  (JNIEnv * env, jobject jb){
      printf("%s","cpp library\n");
}

内容很简单,就是打印一句话。 接下来就是编译,为了方便,我们使用make工具来执行编译过程。这里需要编写Makefile。对Makefile不熟的兄弟可以参考Makefile文件编写。对g++不熟的兄弟可以参考gcc编译参数

libcpp.so : CppLib.cpp
    g++ -o $@ $+ -fPIC -shared -I/usr/local/java/jdk1.8.0_144/include -I/usr/local/java/jdk1.8.0_144/include/linux

.PHONY : clean
clean :
    -rm libcpp.so

这里主要有几个参数需要注意

  • -fPIC -shared代表编译成动态库
  • -I/usr/local/java/jdk1.8.0_144/include -I/usr/local/java/jdk1.8.0_144/include/linux引入jni相关的头文件。我的jdk就安装在/usr/local/java/jdk1.8.0_144

接下来就是编译,直接执行make命令,成功生成libcpp.so文件。linux下库文件有个特点就是固定以lib开头,.so为扩展名。

运行

得到so文件后,接下来就编译JavaMain.java。执行

javac JavaMain.java

得到JavaMain.class

执行:

java -Djava.library.path='.' JavaMain

java一般使用两个path:classpath 和 java.library.path classpath是指向jar包的位置 java.library.path是非java类包的位置如(dll,so)

结果:

[root@localhost jni]# java -Djava.library.path='.' JavaMain
Ok!
cpp library

扩展(有包名的情况)

有不少兄弟在正常的项目开发中,javah和java命令会出现各种错误,比如"找不到**类"。这里我就做一个完整的示例。

2.png

有以下几点需要注意:

  • 执行javah和java命令要在源码目录下,也就是src/java目录下。
  • 执行java命令来运行时候,需要制定java.library.path的路径。
/**
* 在java目录下
*
* 生成头文件
* javah com.eric.demo.JavaMain
*
* 编译
* javac com.eric.demo.JavaMain.java
*
* 运行
* java com.eric.demo.JavaMain  -Djava.library.path=/code/jni2/src/main/jni
*/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android的JNI【实战教程】6⃣️--温控计

    demo下载地址:http://download.csdn.net/detail/github_33304260/9860547

    先知先觉
  • JNI动态注册native方法及JNI数据使用

    前言 或许你知道了jni的简单调用,其实不算什么百度谷歌一大把,虽然这些jni绝大多数情况下都不会让我们安卓工程师来弄,毕竟还是有点难,但是我们还是得打破砂锅知...

    xiangzhihong
  • rust 开发编译 Android 动态库实践

    rust 的学习曲线比较陡峭,在开始学习之前建议看看王垠的这篇文章 《如何掌握所有的编程语言》,地址如下:

    glumes
  • Android:JNI 与 NDK到底是什么?(含实例教学)

    本文根据版本的不同介绍了两种在Android Studio中实现 NDK的方法:Android Studio2.2 以下 & 2.2以上

    Carson.Ho
  • 如何在Android Studio下进行NDK开发

    先看什么是JNI?JNI的全称就是Java Native Interface,即java本地开发接口。可能大家和我一样,一听到接口什么的就犯懵:“我也知道这...

    砸漏
  • Android跨进程通信IPC之3——关于"JNI"的那些事

    在分析IPC基于Android 6.0)的过程中,里面的核心部分是Native的,并且还包含一些linux kernel,而作为Android开发者看到的代码大...

    隔壁老李头
  • Android JNI(一)——NDK与JNI基础

    Android 平台从一开就已经支持了C/C++了。我们知道Android的SDK主要是基于Java的,所以导致了在用Android SDK进行开发的工程师们都...

    隔壁老李头
  • Java关键字——native

      本篇博客我们将介绍Java中的一个关键字——native。   native 关键字在 JDK 源码中很多类中都有,在 Object.java类中,其 ge...

    IT可乐
  • Android NDK Hello

    Android应用程序访问android的根文件系统中的文件时,由于应用程序的权限限制,无法访问这些文件,怎么办?

    阳光岛主

扫码关注云+社区

领取腾讯云代金券