移植心得---android平台
来源:互联网 发布:神机妙算软件培训 编辑:程序博客网 时间:2024/05/16 05:23
目前的情况: android平台的UI开发语言最好选择是JAVA,也是google推荐使用的; OCR引擎是C编写的,用JAVA改写显然不现实 OS: Windows XP SP2 JDK: 1.6.0_06 Toolchins: arm-2008q3-41-arm-none-linux-gnueabi + cygwin SDK: android-sdk-windows-1.0_r1 IDE: eclipse v3.4.1 考虑采用JNI(Java Native Interface)来解决这个问题,由于要用Java来调用引擎,所以需要将引擎编译成so文件(shared library) 1. Android环境搭建 a) 安装JAVA 安装jdk并设置相应的环境变量。我在这里是安装到D:/Java/jdk1.6.0_06 (为了避免路径的问题,在路径的选择上尽量避免使用到空格) 解压缩SDK到硬盘上(我是解压到J:/android目录下,如J:/android/emulator/android-sdk-windows-1.0_r1),添加相应的环境变量(path= J:/android/emulator/android-sdk-windows-1.0_r1/tools),并在C:/Documents and Settings/chongxishen/Local Settings/Application Data目录下创建一个Android的文件夹(假设C是系统盘的盘符),然后到J:/android/emulator/android-sdk-windows-1.0_r1/tools目录下用emulator -wipe-data启动模拟器来完成初始化。之所以在启动之前创建Android文件夹是为了避免模拟器启动过程中创建文件夹失败。 解压缩eclipse,并安装android的插件,然后设置Android的SDK路径。详细请参考http://code.google.com/android/intro/installing.html d) 安装编译器 安装arm-2008q3-41-arm-none-linux-gnueabi到D:/CodeSourcery/SourceryGppLite(同样,路径尽量避免出现空格) 我们可以模仿Benno的方法来确认。详细请参考http://benno.id.au/blog/2007/11/13/android-native-apps 我们可以参考Motz的文章(详细请参考http://honeypod.blogspot.com/2007/12/shared-library-hello-world-for-android.html)。首先我们需要编写Shared library相应的makefile文件。由于是在windows环境,所以我们需要安装一个交叉编译环境,这里我选择cygwin。 当然,我们的目标是通过JAVA来调用这个so文件,所以我们还要move on。这样我们就要涉及到JNI了。通过网上查找资料,我们了解到,对于android 1.0,google是不支持JNI的,但我们知道android的内核是linux,所以应该是有办法达到我们的目标的。 C的函数如下: #if defined(__cplusplus) extern "C" { #endif char *pDataPath, char *pConfigFile, int nLanguage); EXPORT int HC_CloseBCR(BEngine **pEngine); EXPORT int HC_DoImageBCR(BEngine *pEngine, BImage *pImage, BField **ppField); } #endif { static { try { System.load("/data/hcbcr/libocrengine.so"); } catch (Exception e) { //Log.e("JNI", e.toString()); } } /* * NOTE: * Use long type instead of Pointer value of the real C pointer. * Type int is also OK, but Use long to be 64-bit safe. * * Here just list all APIs of OCR Engine, MAYBE will write a class * to wrap this class for better encapsulation and easy usage. */ /// native function list public native int startBCR(long[] ppEngine, byte[] pDataPath, byte[] pConfigFile, int nLanguage); public native int closeBCR(long[] ppEngine); public native int doImageBCR(long pEngine, long pImage, long[] ppField); // … 这里部分函数省略 /// public static void main(String args[]) { OCR ocr = new OCR(); //ocr.startBCR() } } 注意其中加粗体部分:使用System.load能够加载非系统路径(/System/lib)下的so文件,因为默认/System下权限都是read-only(当然我们可以用adb remount来更改为有写的权限);使用static可以避免so被多次加载到内存,这点跟C++类中的static变量类似,所有的instances都共享。 这里有2点需要注意: 1. 很多资料上都提到由javah产生的OCR.h不能改动,但在android平台,我发现需要添加2个函数: JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved); JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved); #define PACKAGE_NAME "com.android.hcbcr.OCR" #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) { "startBCR", "([J[B[BI)I", (void *)Java_OCR_startBCR }, { "closeBCR", "([J)I",(void *) Java_OCR_closeBCR }, { "doImageBCR", "(JJ[J)I", (void *)Java_OCR_doImageBCR }, // 省略部分函数 }; * In order to use the JNI functions introduced in J2SE release 1.2, * in addition to those that were available in JDK/JRE 1.1, a native * library must export a JNI_OnLoad function that returns JNI_VERSION_1_2. * in addition to those that were available in release 1.2, a native * library must export a JNI_OnLoad function that returns JNI_VERSION_1_4. * the VM assumes that the library only requires JNI version JNI_VERSION_1_1. * If the VM does not recognize the version number returned by JNI_OnLoad, * the native library cannot be loaded. */ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) { jint r; jclass k; JNIEnv *env; jint i, size = ARRAY_SIZE(g_jm); k = (*env)->FindClass(env, PACKAGE_NAME); r = (*env)->RegisterNatives(env, k, &g_jm[i], i+1); } } { jint r; jclass k; JNIEnv *env; k = (*env)->FindClass(env, PACKAGE_NAME); (*env)->UnregisterNatives(env, k); } 用Eclipse创建一个测试的Android工程(详细请参考http://code.google.com/android/intro/hello-android.html),需要将OCR.java添加到工程中(其中main函数需要屏蔽掉),在onCreate中添加测试代码: OCR ocr = new OCR(); ocr. startBCR(…); // …. 省略部分代码 这样,我们就完成了目标,就可以为下一步开发高效的Android应用程序打好基础了。
平台环境:
应对的策略:
由于手头上没有Android的真机,所以以下步骤都是在模拟器上验证:
b) 安装emulator
c) 安装IDE
2. Native C application for Android
3. Native C Shared library for Android
好了,通过上面的步骤,我们已经验证了所编译的so文件是可以运行在android平台上的,到这里我们已经迈出了Android平台移植的一小步,但对我们来说已经是一大步了。
4. JNI(关键)
先到官方网站上了解下JNI到底长什么样子(详细请参考http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html)。对于JNI来说,困难的是类型的匹配。这里我只是解释我碰到的问题。
好了,开始编写我们自己的JNI了
EXPORT int HC_StartBCR(BEngine **ppEngine,
/// 省略其他函数
#if defined(__cplusplus)
其中BEngine,BImage和BField都是自定义结构体,JAVA中没有匹配的类型,而还涉及到指针,甚至二级指针。在这里,我们需要做些变通,因为JAVA中没有指针,但考虑到指针无非就是个地址,在32-bit机中相当于int,考虑到以后64-bit机,我在JAVA中采用long来对应C中的一级指针,对于二级指针,则采用数组。由于char在JAVA中是占用2bytes,所以对于char *我采用byte[]来对应。底下是我写的对应OCR的JAVA类。
public class OCR
采用javac OCR.java编译出OCR.class,接下来采用javah –jni OCR产生OCR.h对应C的H文件,添加相应的OCR.c文件,并完成相应函数编写。
代码实现如下:
static JNINativeMethod g_jm[] = {
/*
* In order to use the JNI functions introduced in J2SE release 1.4,
* If the native library does not export a JNI_OnLoad function,
r = (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_4);
for (i = 0; i < size; i++) {
return JNI_VERSION_1_4;
JNIEXPORT void JNI_OnUnload(JavaVM *vm, void *reserved)
r = (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2);
其中com.android.hcbcr是我这个例子的包。至于这2个函数的含义细节可以参考http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html
2. 由于在windows平台,如果采用D:/Java/jdk1.6.0_06/include/win32下的*.h文件,无法编译通过(__int64是windows定义的类型,我们采用的GCC ARM编译器不支持),我们可以用JAVA的linux版本中jdk1.6.0_06/include/linux下的*.h文件
最后将OCR.h/.c文件跟引擎一起编译,这样就可以得到我们想要的Android平台的so文件了。
5. 验证新的so文件
- 移植心得---android平台
- 移植心得---android平台
- 移植心得---android平台
- cocos2dx移植android平台
- cocos2dx移植android平台
- cocos2dx移植android平台
- cocos2dx移植android平台
- ffmpeg android 平台移植
- Android平台移植ifstat
- Android平台移植FFmpeg
- android平台移植valgrind
- tetware移植 to android心得
- S3c6410平台Android移植(图)
- 移植Busybox到Android平台
- ffmpeg移植到android平台
- android平台工程移植问题
- android平台工程移植问题
- Android跨平台移植经验之谈
- Silverlight5正式发布新特性
- 深入浅出正则表达式
- Devexpress gridControl 刷新
- Win7下Vmware虚拟机共享上网设置
- 这不是我想要的shell
- 移植心得---android平台
- SQL2005备份还原问题
- 浅析JavaScript的写类方式
- zoj 2010 || poj 1380 Equipment Box
- 负号提前BAPI(-)
- 《并行环境下实现九大行星问题》
- 小绿人——从APK图标开始.附签名工具
- 婚庆用品店 挖掘甜蜜“金矿”
- mongodb和redis(未完)