使用AndroidNDK测试Linux驱动 第3页
75. if (pstr != NULL)
76. {
77. // 向/dev/wordcount设备文件写入字符串
78. write(dev,pstr, strlen(pstr));
79. }
80. // 关闭/dev/wordcount设备文件
81. close(dev);
82.}
编写上面的代码有一个重点就是jstring_to_pchar函数。该函数可以将jstring类型的数据转换成char*类型的数据。转换的基本思想就是调用Java方法String.getBytes,获取字符串对应的字节数组(jbyteArray)。由于write函数需要的是char *类型的数据,因此,还必须将jbyteArray类型的数据转换成char *类型的数据。采用的方法是先将jbyteArray类型的数据转换成jbyte类型的数据,然后调用memcpy函数将jbyte类型的数据复制到使用malloc函数分配的char *指针空间中。在jstring_to_pchar函数中有如下的一行代码。
jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B"];
看到getMethodID方法最后一个参数的值是"(Ljava/lang/String;)[B",可能Android NDK初学者会对此感到困惑,以为是写错了。实际上这是JNI(Android NDK程序实际上就是遵循JNI规则的程序)对方法参数和返回类型的描述。在JNI程序中为了方便描述Java数据类型,将简单类型使用了一个大写英文字母表示,如表6-1所示毕业论文 。
除了表6-1所示的Java简单类型外,还有一些数据类型需要在JNI代码中与其对应。表6-2是这些数据类型在JNI中的描述符。
从表6-2所示的数据类型对照关系很容易想到本例中的"(Ljava/lang/String;)[B"是什么意思。jstring_to_pchar函数调用的是如下的getBytes方法的重载形式。
public byte[] getBytes(String charsetName) throwsUnsupportedEncodingException
在JNI中调用Java方法需要指定方法参数和返回值的数据类型。在JNI中的格式如下:
"(参数类型)返回值类型"
getBytes方法的参数类型是String,根据表6-2的描述,String类型中JNI在的描述符是"Ljava/lang/String; "。getBytes方法的返回值类型是byte[]。这里就涉及到一个数组的表示法。在JNI中数组使用左中括号([]表示,后面是数组中元素的类型。每一维需要使用一个“[”。byte[]是一维字节数组,所以使用"[B"表示。如果是byte[][][],应使用"[[[B"表示。如果Java方法未返回任何值(返回值类型是void),则用V表示。如void mymethod(int value)的参数和返回值类型可表示为"(I)V"。
Android NDK程序还需要一个Android.mk文件,代码如下:
[html] view plaincopyprint?
01.LOCAL_PATH := $(call my-dir)
02.
03.include $(CLEAR_VARS)
04.
05.LOCAL_MODULE := ndk_test_word_count
06.LOCAL_SRC_FILES := ndk_test_word_count.c
07.
08.include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ndk_test_word_count
LOCAL_SRC_FILES := ndk_test_word_count.c
include $(BUILD_SHARED_LIBRARY)
在编写Java代码调用JNI函数之前,先看一下本例的界面,如图6-18所示。
读者需要先在PC上运行build.sh脚本文件安装word_count驱动。然后单击“从/dev/wordcount读取单词数”按钮,会在按钮下方输出当前/dev/wordcount设备文件中统计出的单词数。读者也可以在输入框中输入一个由空格分隔的字符串,然后单击“向/dev/wordcount写入字符串”按钮,再单击“从/dev/wordcount读取单词数”按钮,就会统计出字符串中包含的单词数,效果如图6-19所示。
下面看一下本例中Java部分(WordCountNDKTestMain.java)的完整代码。
[java] view plaincopyprint?
01.package mobile.android.word.count.ndk;
02.
03