jni浅析

来源:互联网 发布:手机淘宝链接打不开 编辑:程序博客网 时间:2024/05/30 23:12

java运行于虚拟机,执行的是java特定的字节码,不是设备的机器指令,为了能与本地代码可交互,android设计了java native interface,简称jni,一般jni库说的是按照jni规则编写的了相应调用接口的c/c++库。jni库中包含调用和被java调用的本地代码函数,被java调用的函数需要按照特定的规则进行声明,比如,在apk源码中声明了一个NativeCaller类,这个类所在packagecom. nativecaller,那么声明的jni c/c++接口函数应该如下所示:

 

JNIEXPORT int JNICALL Java_com_nativecaller_NativeCaller_add(JNIEnv*env1, jobject obj, jint a, jint b,jstring jstr, jbyteArray jchararray)

{

      char*str  =  (char*)env->GetStringUTFChars(jstr,0);

      unsignedchar * buff = (unsigned char*)env->GetByteArrayElements(jchararray, 0);   

     

      ////usestr and buff to do some

     

env->ReleaseByteArrayElements(jchararray,buff, 0);

    env->ReleaseStringUTFChars(jstr, str  );

 

      returna+b;

}

 

c/c++本地代码调用java代码名似乎没有命名限制,在java随便一个类中声明一个类成员函数,声明如下:

public voidgetData (int a, String str,byte[] data,int datalen){

    Log.e("info","str:" +str+data.len="+ data.length +"len="+datalen);

}

然后在c/c++里面这样使用这个函数:

首先从环境获取java函数句柄,

g_CallBackObj =env->NewGlobalRef(context);

g_CallBack_getData =env->GetMethodID(clazz, " getData ", "(ILjava/lang/String;[BI)V");

 

 

然后在c/c++调用

void getData (int a, char*str, char*data, intdatalen)

{

      Mutex::AutolockautoLock(g_CallbackContextLock);

 

      if(g_CallBackObj!= NULL && g_CallBack_ getData!= NULL)   

      {

           jstringjstr = m_envLocal->NewStringUTF(str);

            jbyteArray  jBuff = m_envLocal ->NewByteArray(datalen);

            m_envLocal ->SetByteArrayRegion(jBuff,0, len, (jbyte*)data);  

           m_envLocal->CallVoidMethod(g_CallBackObj,g_CallBack_getData, a, jstr, jBuff,datalen);

m_envLocal->DeleteLocalRef(jBuff);

           m_envLocal->DeleteLocalRef(jstr);

      }

}

其中m_envLocal在执行上面回调的线程启动的地方如下面这样获得:

JNIEnv * m_envLocal;

 

int status = g_JavaVM->GetEnv((void **)& m_envLocal, JNI_VERSION_1_4);

      if(status< 0)

      {

           status= g_JavaVM->AttachCurrentThread(&m_envLocal, NULL);

           if(status< 0)

           {

                 Log("AttachCurrentThreadFailed!!");

                 returnNULL;

           }

      }   

0 0
原创粉丝点击