zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    37. Sudoku Solver(js)
    36. Valid Sudoku(js)
    35. Search Insert Position(js)
    34. Find First and Last Position of Element in Sorted Array(js)
    33. Search in Rotated Sorted Array(js)
    32. Longest Valid Parentheses(js)
    函数的柯里化
    俞敏洪:我和马云就差了8个字
    vue路由传值params和query的区别
    简述vuex的数据传递流程
  • 原文地址:https://www.cnblogs.com/dpf-learn/p/6749607.html
Copyright © 2011-2022 走看看