📚 Posts

Eclipse 在单个项目下利用 CDT 进行 JNI 开发

目标:我们希望在单个项目下同时进行 C/C++ 和 JNI 开发。

  • 创建 Java 项目 (HelloJNI),并创建 Java 类。
    public class HelloJNI {
        static {
            System.loadLibrary("hello");
        }
    
        private native void sayHello();
    
        public static void main(String[] args) {
            new HelloJNI().sayHello();
        }
    }
    

    根据 shared libraries 的命名规约,每一个 shared library 的 soname 的构成为:”lib 前缀 + library 名称 + .so”,因此,在 Linux 系统中,这段代码实际查找的是 libhello.so。

  • 接着,将项目转换成 C/C++ 项目。New -> Other -> Convert to a C/C++ Project (Adds C/C++ Nature),其中 Project type 选择 Makefile project,Toolchains 选择 Linux GCC,如下图。

    alt text

  • 在项目下创建 jni 文件夹,用于存放 C/C++ 代码,我们在其中创建与 Java 类同名的 C/C++ 文件。
    #include <jni.h>
    #include <stdio.h>
    #include "HelloJNI.h"
    
    JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj)
    {
       printf("Hello World!\n");
       return;
    }
    
  • 在 jni 文件夹下创建 Makefile 文件。
    # Define a variable for classpath
    CLASS_PATH = ../bin
    
    # Define a virtual path for .class in the bin directory
    vpath %.class $(CLASS_PATH)
    
    all : libhello.so
    
    # $@ matches the target, $< matches the first dependancy
    libhello.so : HelloJNI.o
        gcc -Wextra -shared $< -o $@
    
    HelloJNI.o : HelloJNI.c HelloJNI.h
        gcc -fPIC -I/usr/lib/jvm/java/include -I/usr/lib/jvm/java/include/linux -c $< -o $@
    
    # $* matches the target filename without the extension
    HelloJNI.h : HelloJNI.class
        javah -classpath $(CLASS_PATH) $*
    
    clean :
        rm libhello.so HelloJNI.o HelloJNI.h
    

    其中,javah 根据 .class 文件生成对应的 .h 头文件。本例中实际为

    javah -classpath ../bin HelloJNI
    

    该命令会生成相应的 HelloJNI.h 文件。

  • 右击 jni 文件夹,Build Targets -> Create…,在 Target name 处填写 all ,如下图。

    alt text

    Build该target后会在jni目录下生成libhello.so。

  • 运行该 Java 项目,Run As -> Run Configurations,类型选择 Java Application,在 Arguments 面板下的 VM arguments 中填入library路径 -Djava.library.path=jni,如下图。

    alt text

  • 可以在项目根目录下创建makefile文件,此时可省略前述 Create Build Targets 的步骤。
    all :
        cd jni; make
    
    clean :
        cd jni; make clean
    

References

📚 Posts