JNI 过程

    技术2022-05-20  38

    一、综述

    Java程序设计中的java和C/C++之间的调用,实际上在被称之为JNI。

    由于本人从前对java了解并不十分深入,也没有做过java的项目,因此在研究JNI的过程中走了不少弯路。

    下面说下JAVA调用C的整个工作流程。从程序员编程的顺序来说,应该是

     

    编写java调用类à声明native(本地代码调用)à使用javah生成头文件à根据新的头文件编写相关接口à编译

    二、编写java类

    这个比较简单,如上一章说过的

    public class CActivityMain extends Activity {

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

        static {

            System.loadLibrary("my_jni");

        }

        @Override

        public void onCreate(Bundle savedInstanceState)

        {

            super.onCreate(savedInstanceState);

            TextView tv = new TextView(this);

            tv.setText( stringFromJNI() );

            setContentView(tv);

        }

        public native String stringFromJNI();

    }

    其实就是简单的java调用类,我们主要是要把要使用的接口声明在

    public native String stringFromJNI();

    三、生成javah头文件

    很多没有接触过java的人都不大会用这个东东,其实我开始也好生琢磨了很久,其实最简单的使用方法是这样的

    首先先要编译我们的android项目,因为javah算是一个反编译工具,需对编译后的文件使用。

    由于我们编译后的文件是默认放在android项目目录下的bin目录的。

    于是我们打开cmd

    进入项目目录下的bin目录然后输入 javah –jni com.hm.hello.CactivityMain

    其中com.hm.hello是我们要调用ndk的包的名称,CactivityMain是要调用ndk的类的名称,命令示例如下所示

    E:/hello_jni/bin>javah -jni com.hm.hello.CactivityMain

    然后再bin目录下就生成了一个头文件,我生成的头文件如下所示

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

    #include <jni.h>

    /* Header for class com_hm_hello_CActivityMain */

     

    #ifndef _Included_com_hm_hello_CActivityMain

    #define _Included_com_hm_hello_CActivityMain

    #ifdef __cplusplus

    extern "C" {

    #endif

    /*

    * Class:     com_hm_hello_CActivityMain

    * Method:    stringFromJNI

    * Signature: ()Ljava/lang/String;

    */

    JNIEXPORT jstring JNICALL Java_com_hm_hello_CActivityMain_stringFromJNI

    (JNIEnv *, jobject);

    #ifdef __cplusplus

    }

    #endif

    #endif

    于是我们在编写C/C++代码的时候包含这个头文件,然后实现该头文件中声明函数的实现即可。

    如我写的实现:

    #include "my_jni.h"//放在同级目录下的,刚才生成的头文件(改过名)

    JNIEXPORT jstring JNICALL Java_com_hm_hello_CActivityMain_stringFromJNI(JNIEnv* env, jobject)

    {

    return env->NewStringUTF("12345");

    }

    不过有一点要注意,因为我的这个实现文件是用的cpp,所以可以这样调用。假如实现文件使用.c写的,那么return env->NewStringUTF("12345");需要改为return (*env)->NewStringUTF(env, "12345");

    之后编译即可,这就是我们使用ndk的一个基本流程


    最新回复(0)