美文网首页
Java JNI本地调用实例

Java JNI本地调用实例

作者: 西5d | 来源:发表于2020-10-15 20:05 被阅读0次

背景

JNI 全称是Java Native Interface ,用来实现java对c/c++等编译方法的调用。常见如Jdk Object Thread 等类中也有许多基于jni的Native方法,还有一些与硬件、操作系统直接交互或者为了提高执行性能而使用jni调用。

说明

本期介绍一个使用jni示例,用java调用c++生成的链接库,实际执行c++实现的方法。大致步骤如下:

  1. 定义java native方法;
  2. 编译java得到class字节码;
  3. 生成jni链接使用的c/c++头文件;
  4. 编写c/c++代码实现;
  5. 生成链接库;
  6. 配置java执行链接库地址;
  7. 执行jni实现示例;

代码

生成java代码和编译

注意这里笔者本地根目录是/export/code/java,且这里额外创建了package

#cd /export/code/java
#mkdir -p com/test

编写Java代码

//NativeTest.java
package com.test;
public class NativeTest {
    //定义方法
    public final native void sayHello();
    //注意名字对应结果库 libxxx.so,否则找不对
    static {
        System.loadLibrary("echoHello");
     
    }
    //调用结果
    public static void main(String[] args){
        NativeTest test = new NativeTest();
        test.sayHello();
    }
}

注意loadLibrary加载的名称要对应libxxx.so的xxx部分

生成class字节码

#javac com/test/NativeTest.java

javah 生成头文件

当前目录在/export/code/java

#javah com.test.NativeTest

生成头文件如下, com_test_NativeTest.h

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

#ifndef _Included_com_test_NativeTest
#define _Included_com_test_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_test_NativeTest
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_test_NativeTest_sayHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

编写c++代码

这部分用来编写c++代码,具体实现我们在java中定义的native方法。当前目录在/export/code/java

//EchoHello.cpp
#include "jni.h"
#include "com_test_NativeTest.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_com_test_NativeTest_sayHello(JNIEnv *env, jobject obj){
 //执行的结果
 printf("hello , my hello !\n");
 return;
}


int main(){
 return 0;
}

编译c++代码,生成链接库

使用命令将cpp编译,生成链接库so文件。

#g++ -fPIC  -I /export/usr/jdk/jdk1.8.0_201/include/ -I /export/usr/jdk/jdk1.8.0_201/include/linux/ -shared EchoHello.cpp  -o libechoHello.so

注意:1. 需要根据环境配置使用 -I 参数引入对应的依赖,比如笔者本地ubuntu 使用 /include/linux 。 2. 注意这里链接库的命名。

关于PIC参数解释:fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。[2]

运行结果

将当前目录添加到链接库地址

这是必须的一步,将本地生成的链接库文件添加到java执行环境中才能使用。(以下命令运行在*nix环境)

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/export/code/java

结果展示

my@localhost:/export/code/java$ java com.test.NativeTest 
hello , my hello !
my@localhost:/export/code/java$ 

参考链接

可能由于未知因素影响,部分链接会失效

  1. Jni的实现
  2. gcc编译参数-fPIC的一些问题

相关文章

  • Java JNI本地调用实例

    背景 JNI 全称是Java Native Interface ,用来实现java对c/c++等编译方法的调用。常...

  • JNI介绍

    1 JNI定义 JNI(Java Native Interface),即Java本地接口,JNI是Java调用Na...

  • JNI

    JNI: Java Native Interface ;Java本地调用 JNI功能: 可以实现Java函数和Na...

  • 四、MagicCamera3#C++与Kotlin之间的衔接

    NDK和JNI JNI是Java Native Interface(JAVA本地接口)的缩写,为了方便Java调用...

  • JNI学习总结(基础篇)

    基本概念 JNI JNI(Java Native Interface),Java本地接口,是为方便java调用C或...

  • 一、Jni开发:jni的使用

    一、Jni是什么? JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1...

  • CMakeList

    JNI(Java Native Interface):Java本地接口。是为了方便Java调用c、c++等本地代码...

  • JNI-Linux

    JNI是Java Native Interface的缩写,Java源生接口/本地调用/本地接口,允许Java和其他...

  • (十四)JNI和NDK的编程

    JNI是Java Native Interface(JAVA本地接口)的缩写,为了方便Java调用C、C++等本地...

  • 初识安卓JNI开发,ndk-build+Android.mk+A

    前言 JNI是什么?JNI是Java Native Interface的缩写,即为java的本地调用,他其实就是一...

网友评论

      本文标题:Java JNI本地调用实例

      本文链接:https://www.haomeiwen.com/subject/lvwopktx.html