• Linux上从Java程序中调用C函数


    原则上来说,“100%纯Java”的解决方法是最好的,但有些情况下必须使用本地方法。特别是在以下三种情况:

    • 需要访问Java平台无法访问的系统特性和设备;
    • 通过基准测试,发现Java代码比其他语言编写的等价代码慢得多;
    • 其他语言编写的代码已经经过大量测试和调试,并且知道如何将其导出到所有的目标平台上。

      Java平台有一个用于和本地C、C++代码进行互操作的API,称为Java本地接口(JNI)。下面将举例讨论Linux平台下的JNI编程。

    1. 创建java类文件

      创建一个nativeTest包,在包下新建HelloNative.java文件。

    复制代码
     1 package nativeTest;
     2 
     3 /**
     4  * Created by jiax on 2016/12/30.
     5  */
     6 public class HelloNative {
     7     // 静态初始化代码块,保证虚拟机在第一次使用该类时就会装载库
     8     static {
     9         System.loadLibrary( "HelloNative" );
    10     }
    11 
    12     // native 关键字表示本地方法,提醒编译器该方法将在外部定义
    13     public static native void greeting();
    14 
    15     // 测试greeting()函数
    16     public static void main(String[] args) {
    17         greeting();
    18     }
    19 }
    复制代码

    2. 生成.h头文件

      使用以下命令生成一个C的头文件,nativeTest_HelloNative.h

    1 javac HelloNative.java
    2 cd ..
    3 javah nativeTest.HelloNative

      生成的nativeTest_HelloNative.h如下:

     1 /* DO NOT EDIT THIS FILE - it is machine generated */
     2 #include <jni.h>
     3 /* Header for class nativeTest_HelloNative */
     4 
     5 #ifndef _Included_nativeTest_HelloNative
     6 #define _Included_nativeTest_HelloNative
     7 #ifdef __cplusplus
     8 extern "C" {
     9 #endif
    10 /*
    11  * Class:     nativeTest_HelloNative
    12  * Method:    greeting
    13  * Signature: ()V
    14  */
    15 JNIEXPORT void JNICALL Java_nativeTest_HelloNative_greeting
    16   (JNIEnv *, jclass);
    17 
    18 #ifdef __cplusplus
    19 }
    20 #endif
    21 #endif
    nativeTest_HelloNative.h

      这个文件是在nativeTest文件夹外生成的,需要拖到nativeTest文件夹里面。  

    3. 创建.c文件

      新建一个HelloNative.c文件,写出greeting()函数的实现代码。

    1 #include <stdio.h>
    2 #include "nativeTest_HelloNative.h"
    3 
    4 JNIEXPORT void JNICALL Java_nativeTest_HelloNative_greeting(JNIEnv *env, jobject c1) {
    5     printf("Hello Native!!
    ");
    6 }

    4. 编译一个动态链接库

      使用Linux下的gcc编译器,命令如下:

    gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o libHelloNative.so HelloNative.c

      生成libMyNative.so文件,此时整个nativeTest目录文件结构如下:

    5. 运行测试

      输入如下命令运行HelloNative.class文件。

    java nativeTest.HelloNative 

      如果出现如下错误:

      则需要把libHelloNative.so所在文件夹加入java.library.path,使用命令:

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:..../nativeTest

      最终结果如下。

     6 总结

      总的来说,将一个本地方法链接到Java程序中需要经过以下5个步骤:

    1. 在Java类中声明一个本地方法;
    2. 运行javah以获得包含该方法的C声明的头文件;
    3. 用C实现该本地方法;
    4. 将代码置于共享类库中;
    5. 在Java程序中加载该类库。

    附录——本文中用到的工具版本

    JDK——1.8.0_111

    gcc——4.8.5

  • 相关阅读:
    poj2002 poj3432 正方形个数 (hash,二分)
    置换群
    poj1995快速幂取余
    poj3983 (24点)
    判断二叉树是否是完全二叉树
    判断两个二叉树是否同构(相似)
    poj2187 最远点对问题
    poj2079 求最大的三角形面积
    poj3714 最近点对
    Linq学习笔记延迟操作符(分区操作符)
  • 原文地址:https://www.cnblogs.com/dpf-learn/p/6749607.html
Copyright © 2020-2023  润新知