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

  • 相关阅读:
    开发安全测试工具 ,推荐6款完全免费的工具
    Asp.net MVC 出现IQueryable<T> 未包含“Include”的定义
    Windows系统Git安装教程(详解Git安装过程)
    窗体进行自动适应窗口
    C# ObservableCollection两个字段排序的情况
    Advanced Installer 14.9 – WPF或winform应用程序打包成exe文件
    DotNetCore部署(IIS)踩坑记
    DotNetCore部署(IIS)文档
    windows系统中Dotnet core runtime 安装后,无法启动次程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll的解决方法
    解决Git在添加ignore文件之前就提交了项目无法再过滤问题
  • 原文地址:https://www.cnblogs.com/622698abc/p/3812918.html
Copyright © 2011-2022 走看看