设为首页 加入收藏

TOP

[ndk,2]ndk开发案例和错误处理(四)
2014-11-23 21:12:37 来源: 作者: 【 】 浏览:18
Tags:ndk 开发 案例 错误 处理
r;

}

3、注意:

①、在c中接收java中int类型的数据时:由于int类型的数据java和c中的长度相同,c可以直接使用java传递过来int型数据。

②、c接收了java中的字符串数据 ,由于c中没有字符串类型,首先c要先将java的字符串类型转成char数组类型;

在c语言中 字符串的结果都是以/0这样一个标示 作为字符串的结尾

下面是具体的转换方法:

/**

* 工具方法

* 作用: 把java中的string 转化成一个c语言中的char数组

* 接受的参数 envjni环境的指针

* jstr 代表的是要被转化的java的string 字符串

* 返回值 : 一个c语言中的char数组的首地址 (char 字符串)

*/

char* Jstring2CStr(JNIEnv* env, jstring jstr)

{

char* rtn = NULL;

jclass clsstring = (*env)->FindClass(env,"java/lang/String");

jstring strencode = (*env)->NewStringUTF(env,"GB2312");

jmethodID mid =

(*env)->GetMethodID(env,clsstring,"getBytes","(Ljava/lang/String;)[B");

// String.getByte("GB2312");

jbyteArray barr=

(jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode);

jsize alen = (*env)->GetArrayLength(env,barr);

jbyte* ba = (*env)->GetByteArrayElements(env,barr,JNI_FALSE);

if(alen > 0)

{

rtn = (char*)malloc(alen+1); //"\0"

memcpy(rtn,ba,alen);

rtn[alen]=0;

}

(*env)->ReleaseByteArrayElements(env,barr,ba,0); //

return rtn;

}

③、在将java 中int类型的数组传递c代码中 ,获取数组的长度,再获取数组的首地址后获取每一个元素。

④、java不会将字符串数组传给c代码, 而是将字符串数组元素用:隔开转成字符串传给c代码.

十二、c代码调用java代码:案例:c代码调用java 代码 弹出一个土司.

主要步骤:首先java调用c代码的方法 在c代码中再调用java代码:

1、在java类中定义方法:

public class DemoActivity extends Activity {

static{

System.loadLibrary("Hello");

}

public native void callMethod1();

//按钮的点击事件

public void showToast(View view){

//1.调用底层的c代码

//2.c代码里面 让c语言的代码调用java代码 显示出来一个土司

callMethod1();

}

//被c调用的方法

public void javaShowToast(String message){

Toast.makeText(this, message, 0).show();

}

}

2、c代码:类似java中的反射,先获取java类的字节码文件,再获取method对象,再执行该方法。

#include

#include "cn_itcast_ndkcallback_DemoActivity.h"

#include

#define LOG_TAG "System.out"

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,__VA_ARGS__)

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG,__VA_ARGS__)

//参数env 是JNIEnv的指针

// obj 代表的是调用这个c代码的java对象

JNIEXPORT void JNICALLJava_cn_itcast_ndkcallback_DemoActivity_callMethod1

(JNIEnv * env , jobject obj) {

// 找到 java中的代码javaShowToast 调用他 让java代码显示出来一个土司

//

// Method method = DemoActivity.class.getMethod("javaShowToast",new Class[]{String.class});

// method.invoke(obj, "string");

// 1. 寻找要调用的java代码的字节码 class

//jclass (*FindClass)(JNIEnv*, const char*);

//获取java的类的字节码。FindClass方法参数(env ,java类类路径)

jclass jclazz = (*env)->FindClass(env,"cn/itcast/ndkcallback/DemoActivity");

// 2.寻找当前jclass里面的方法的id

// jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*,const char*);

//获取字节码中指定方法的id。GetMethodID方法参数(env ,字节码文件,方法名, 该方法签名)

//方法签名通过javap 工具获得;

jmethodID jshowtoastmethod =

(*env)->GetMethodID(env,jclazz,"javaShowToast","(Ljava/lang/String;)V");

//3. 调用该方法

// void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);

//执行方法:CallVoidMethod方法参数(env,obj ,方法id,传递到被调用java方法中的参数)

(*env)->CallVoidMethod(env,obj,jshowtoastmethod,(*env)->NewStringUTF(env,"hi from c"));

}

3、注意: 获取方法签名的方法是:在命令行中使用javap 工具:

命令为: javap -s 完整类名 。 就可以获取指定类中所有方法的方法签名。

十二、c代码调用java代码方法的常见案例:

1、定义被c代码调用的java的方法

public class DataProvider{

//C调用java空方法

public voidhelloFromJava(){

System.out.println("我是java的空方法");

}

//C调用java中的带两个int参数的方法

public int Add(int x,int y){

int result =x+y;

System.out.println("相加的结果为"+result);

首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇BMP文件右旋90度[c语言] 下一篇寻找直方图中面积最大的矩形(C语..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: