zoukankan      html  css  js  c++  java
  • 在Java中调用C

    在Java代码中通过JNI调用C函数的步骤如下:

    第一步:编写Java代码

    第二步:编译Java代码(javac Java文件)

    第三步:生成C代码头文件(javah java类名,自动生成)

    第四步:编写C代码(实现C代码头文件里面的函数)

    第五步:生成C共享库(使用工具编译生成C共享库,win下面为dll文件,Linux下面为so文件)

    第六步:运行Java程序(java 类名)

    一、编写Java代码

    首先编写调用C语言的Java源代码HelloJNI.java

    public class HelloJNI {
    native void printHello();
    
    native void printString(String str);
    
    static {
    System.loadLibrary("hellojni");
    }
    
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    HelloJNI myJNI = new HelloJNI();
    myJNI.printHello();
    myJNI.printString("Hello world form printString function!");
    }
    }
    

    说明:

    1. 在Java类中,使用”native”关键字,声明本地方法,该方法与用C/C++编写的JNI本地函数相对应。”native”关键字告知Java编译器,在Java代码中带有该关键字的方法只是声明,具体由C/C++等其它语言编写实现。

    2. 在Java类中声明了本地方法之后,接下来,调用System.loadLibrary()方法,加载具体实现本地方法的C运行库(在Java中加载本地运行库通常使用静态块(static block))。System.loadLibrary()方法加载由字符串参数指定的本地库,在不同操作系统平台下,加载的C运行库不同。在Window下面,调用System.loadLibrary(“hellojni”),则hellojni.dll会被加载;在Linux下面,则会加载libhellojni.so文件。

    二、编译Java代码

    使用javac编译java源代码

    javac HelloJNI.java
    

    三、生成C代码头文件

    使用javah自动生成C代码头文件

    javah HelloJNI
    

    生成的头文件HelloJNI.h见下:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class HelloJNI */
    
    #ifndef _Included_HelloJNI
    #define _Included_HelloJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
    * Class: HelloJNI
    * Method: printHello
    * Signature: ()V
    */
    JNIEXPORT void JNICALL Java_HelloJNI_printHello
    (JNIEnv *, jobject);
    
    /*
    * Class: HelloJNI
    * Method: printString
    * Signature: (Ljava/lang/String;)V
    */
    JNIEXPORT void JNICALL Java_HelloJNI_printString
    (JNIEnv *, jobject, jstring);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    四、编写C代码

    实现C头文件中的方法,hellojni.c文件见下:

    #include "HelloJNI.h"
    #include <stdio.h>
    JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject obj)
    {
    printf("Hello world!
    ");
    return ;
    }
    
    JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv *env, jobject obj, jstring string)
    {
    const char * str = (*env)->GetStringUTFChars(env,string,0);
    printf("%s!
    ",str);
    return ;
    }
    

    说明:

    1、GetStringUTFChars ()是JNI函数,用来将Java字符串转换成C语言字符串。JNI提供了多种JNI函数,用来处理C字符串与Java字符串的转换,具体参见http://blog.csdn.net/qinjuning/article/details/7595104

    五、生成C共享库

    在Linux下测试,书写makefile文件,编译刚才所写的C代码,生成.so文件;

    makefile文件见下:

    libhellojni.so:hellojni.o makefile
    gcc -Wall -rdynamic -shared -o libhellojni.so hellojni.o
    hellojni.o:hellojni.c HelloJNI.h
    gcc -Wall -c hellojni.c -I./ -I/usr/lib/jdk/include -I/usr/lib/jdk/include/linux -fPIC
    cl:
    rm -rf *.o *.so
    

    使用make命令编译

    make
    

    说明:

    1、生成的so文件必须命令为libhellojni.so,与java代码中的System.loadLibrary("hellojni")对应;

    2、在编译时,必须加上-fPIC,否则,编译时报以下错误:

    /usr/bin/ld: hellojni.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
    hellojni.o: could not read symbols: Bad value
    collect2: ld 返回 1
    make: *** [hellojni.so] 错误 1

    3、gcc和rm前面必须是一个tab空格,否则makefile格式不正确;

    六、运行java程序

    在运行java程序之前,要把生成的so文件加入LD_LIBRARY_PATH中,如下:

    export LD_LIBRARY_PATH=./
    

    否则,在运行java程序的时候报错,错误信息见下:

    Exception in thread "main" java.lang.UnsatisfiedLinkError: no hellojni in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)
    at java.lang.Runtime.loadLibrary0(Runtime.java:823)
    at java.lang.System.loadLibrary(System.java:1028)
    at HelloJNI.<clinit>(HelloJNI.java:7)
    Could not find the main class: HelloJNI. Program will exit.
    

    运行java程序:

    java HelloJNI
    

    结果见下:

    Hello world!
    Hello world form printString function!!
  • 相关阅读:
    商贸通帐套隐藏方法
    固定资产打开提示:上年度数据未结转!
    ZOJ 2432 Greatest Common Increasing Subsequence
    POJ 1080 Human Gene Functions
    POJ 1088 滑雪
    POJ 1141 Brackets Sequence
    POJ 1050 To the Max
    HDOJ 1029 Ignatius and the Princess IV
    POJ 2247 Humble Numbers
    HDOJ 1181 变形课
  • 原文地址:https://www.cnblogs.com/Cherise/p/4350810.html
Copyright © 2011-2022 走看看