Android JNI(JNI(JAVA同C++配合使用)

    技术2022-05-19  29

    实现功能: JAVA 调用 C/C++ 底层代码

    须知: 只有程序成为处理器杀手的时候,以及保证安全的时候才用 NDK

    环境: cygwin+android sdk+android ndk eclipse cdt eclipse sdt

    例子:详细请查看“历上最强的 NDK 入门与实践资料”文档

    实现细节:

    Jni.java

    package com.yarin.android.HelloNDK;

    public class Jni

    {

      /* 声明本地方法 */

      // 得到一个 int 型数据

      public native int getCInt ();

      // 得到一个字符串数据

      public native String getCString ();

    }

     

     

    HelloNDK .java

     

    package com.yarin.android.HelloNDK;

    import android.app.Activity;

    import android.os.Bundle;

    import android.widget.TextView;

    public class HelloNDK extends Activity

    {

        // 装载动态库“ libHello.so

        static

        {

            System.loadLibrary("HelloNDK");

        }

        /** Called when the activity is first created. */

        @Override

        public void onCreate(Bundle savedInstanceState)

        {

           super.onCreate(savedInstanceState);

           Jni jni = new Jni();

           TextView textView = new TextView(this);

           // 调用原生方法

           textView.setText(jni.getCString()+Integer.toString(jni.getCInt()));

           setContentView(textView);

        }

    }

     

    生成 JNI 头文件

    下面生成 JNI 头文件啦,使用 javah 命令,对 JNI..java 这个文件生成,别搞错啦!

    使用 cmd 进入 android 项目的 bin 目录中,然后执行 javah -classpath .  -jni cc.androidos.jni.JNI 这个命令。别忘记包名!( ^_^

    如下所示:

     

     

     

    产生如下文件:

     

     

     

     

    将其拷贝到 jni ,代码清单如下:

    /* DO NOT EDIT THIS FILE - it is machine generated */

    #include <jni.h>

    /* Header for class com_yarin_android_HelloNDK_Jni */

     

    #ifndef _Included_com_yarin_android_HelloNDK_Jni

    #define _Included_com_yarin_android_HelloNDK_Jni

    #ifdef __cplusplus

    extern "C" {

    #endif

    /*

      * Class:     com_yarin_android_HelloNDK_Jni

      * Method:    getCInt

      * Signature: ()Ljava /lang /String;

      */

    JNIEXPORT jint JNICALL Java_com_yarin_android_HelloNDK_Jni_getCInt

      (JNIEnv *env, jobject thiz);

     

    /*

      * Class:     com_yarin_android_HelloNDK_Jni

      * Method:    getCString

      * Signature: ()Ljava /lang /String;

      */

    JNIEXPORT jstring JNICALL Java_com_yarin_android_HelloNDK_Jni_getCString

      (JNIEnv *env, jobject thiz);

     

    #ifdef __cplusplus

    }

    #endif

    #endif

    // 防止再次被编译,提高效率

     

    在同源文件夹 jni, 在该目录建立两个文件 android.mk com_yarin_android_HelloNDK_Jni.c

    Android.mk 清单如下:

    LOCAL_PATH : = $(call my-dir)

     

    include $(CLEAR_VARS)

     

    LOCAL_MODULE    : = HelloNDK

    LOCAL_SRC_FILES : = com_yarin_android_HelloNDK_Jni.c

     

    include $(BUILD_SHARED_LIBRARY)

     

    com_yarin_android_HelloNDK_Jni.c 的清单如下:

     

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    #include "com_yarin_android_HelloNDK_Jni.h"

    int add2 ()

    {

        int x,y;

        x = 1000;

        y = 8989;

        x+=y;

        return x;

    }

    JNIEXPORT jint JNICALL Java_com_yarin_android_HelloNDK_Jni_getCInt

      (JNIEnv *env, jobject thiz)

    {

        return add2 ();

    }

    JNIEXPORT jstring JNICALL Java_com_yarin_android_HelloNDK_Jni_getCString

      (JNIEnv *env, jobject thiz)

    {

        return (*env)->NewStringUTF(env, "HelloNDK---->>" );

    }

     

    运行 1.  cygwin

    2.  cd $ANDROID_NDK_ROOT

    3.      ./ndk -build -C samples/myjni

     

     

     

     

    就会在当前目录下生成

     

     

     

     

     

     

     

    这样就产生了 linux 下面的动态链接库( win32 下面为 dll 后缀名)

    整个项目的目录如下:

     

     

    图表 1

    运行实例:截图如下:

     

     

     

    附录:

    其实很好理解的,仅仅是换个了别名而以,定义如下 typedef uint8_t         jboolean;       /* unsigned 8 bits */ typedef int8_t          jbyte;          /* signed 8 bits */ typedef uint16_t        jchar;          /* unsigned 16 bits */ typedef int16_t         jshort;         /* signed 16 bits */ typedef int32_t         jint;           /* signed 32 bits */ typedef int64_t         jlong;          /* signed 64 bits */ typedef float           jfloat;         /* 32-bit IEEE 754 */ typedef double          jdouble;        /* 64-bit IEEE 754 */ #else typedef unsigned char   jboolean;       /* unsigned 8 bits */ typedef signed char     jbyte;          /* signed 8 bits */ typedef unsigned short  jchar;          /* unsigned 16 bits */ typedef short           jshort;         /* signed 16 bits */ typedef int             jint;           /* signed 32 bits */ typedef long long       jlong;          /* signed 64 bits */ typedef float           jfloat;         /* 32-bit IEEE 754 */ typedef double          jdouble;        /* 64-bit IEEE 754 */ #endif typedef jint            jsize; 还有一些调用平时注意的声明 #define JNI_FALSE   0 #define JNI_TRUE    1 #define JNI_VERSION_1_1 0x00010001 #define JNI_VERSION_1_2 0x00010002 #define JNI_VERSION_1_4 0x00010004 #define JNI_VERSION_1_6 0x00010006 #define JNI_OK          (0)         /* no error */ #define JNI_ERR         (-1)        /* generic error */ #define JNI_EDETACHED   (-2)        /* thread detached from the VM */ #define JNI_EVERSION    (-3)        /* JNI version error */ #define JNI_COMMIT      1           /* copy content, do not free buffer */ #define JNI_ABORT       2           /* free buffer w/o copying back */ #define JNIIMPORT #define JNIEXPORT #define JNICALL


    最新回复(0)