首页 > 代码库 > cygwin+ndk+eclipse下JNI技术入门

cygwin+ndk+eclipse下JNI技术入门

1、JNI的编写步骤
1)编写带有native 声明的java类.
2)编译java文件成class类
3)使用javah -jni com.ikags.project.XXXX 编译成.h文件
4)使用C/C++编写代码
5)编写makefile文件,将.h和.c(.cpp)文件编译成.dll(.so)文件
6)将.dll(.so)文件提供给项目,用system.loadLibrary方法调用.

 

2、编写makefile文件
make执行时,自动寻找Makefile(makefile)文件,然后执行编译工作。
在一个Makefile中通常包含下面内容:
1)需要由make工具创建的目标体(target),通常是目标文件或可执行文件。
2)要创建的目标体所依赖的文件(dependency_file)。
3)创建每个目标体时需要运行的命令(command)。

 

3、Android.mk写法
(1)Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件。由于一般情况下
Android.mk和需要编译的源文件在同一目录下,所以定义成如下形式:
LOCAL_PATH:=$(call my-dir)
上面的语句的意思是将LOCAL_PATH变量定义成本文件所在目录路径。
(2)Android.mk中可以定义多个编译模块,每个编译模块都是以include $(CLEAR_VARS)开始
以include $(BUILD_XXX)结束。
include $(CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除除LOCAL_PATH以外的所有LOCAL_XXX变量,
如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIES等。
include $(BUILD_STATIC_LIBRARY)表示编译成静态库
include $(BUILD_SHARED_LIBRARY)表示编译成动态库。
include $(BUILD_EXECUTABLE)表示编译成可执行程序

 

4、jni调用例子
编码前提,cygwin+ndk+eclipse搭建的开发环境,能够正常编译运行
第一个jni测试程序还是打印hello,world
4.1写好java,native方法,以及调用lib名
package jni;
public class Hello
{
    public native void sayHello();
    static
    {
     System.out.println(System.getProperty("java.library.path"));
        System.loadLibrary("hello");
    }
    public static void main(String[] args)
    {
     
        Hello h = new Hello();
        h.sayHello();
    }
}
4.2、使用javah -jni 全包名+类名 编译成.h文件
编译通过后,class文件在工程的bin目录下。
进入到dos状态,cd 到工程的bin目录,运行命令如下:
 javah -jni jni.Hello
正常情况下,jni_Hello.h会出现在bin目录下

4.3、生成.so文件
1)新建hello.c文件
然后我们建立一个C++工程,在src目录下建立一个jni目录,
将刚刚建立好的jni_Hello.h文件copy到jni目录,
并在jni目录下建立一个 hello.c文件,用来实现头文件中声明的方法,代码如下:
#include <jni.h>
#include "jni_Hello.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __cplusplus
}
#endif


JNIEXPORT void JNICALL Java_jni_Hello_sayHello(JNIEnv *env, jobject obj) {
   printf("Hello World !\n");
   return;
}

2)新建Android.mk文件
在jni目录下(即hello-jni.c 同级目录下)新建一个Android.mk文件
LOCAL_PATH := $(call my-dir)
include  $(CLEAR_VARS)
LOCAL_MODULE    := hello
#LOCAL_MODULE,编译的目标对象,以标识你在Android.mk文件中描述的每个模块
LOCAL_SRC_FILES := hello.c
#LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件
include  $(BUILD_SHARED_LIBRARY)
#BUILD_SHARED_LIBRARY表示编译生成共享库

运行cygwin, 到C++工程目录下,如下:
cd cygdrive/c/workspace/hello/src/jni
运行$NDK/ndk-build,如下:
$ ndk-build
Cygwin         : Generating dependency file converter script
Compile thumb  : hello <= hello.c
SharedLibrary  : libhello.so
Install        : libhello.so => libs/armeabi/libhello.so
如果提示信息如上所示,表示.so共享库文件成功生成

so文件拷贝到java的加载库LD_LIBRARY_PATH指向的路径中。

5,运行java工程

 

出处:htpp://blog.sina.com.cn/staratsky