第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > linux android ndk

linux android ndk

时间:2019-08-31 14:09:51

相关推荐

linux android ndk

Android调用so库, so库是c语言编写, 在linux 64位系统+ndk(32位)生成 lib*.so (32位)

1. 所需软件环境:

1)so库开发环境

操作系统: Redhat Server 6.3 x86_64

编译软件:Code::Blocks

Android native开发库:android-ndk-r9c-linux-x86.tar.bz2

[xxx@www ~]$ uname -aLinux 2.6.32-279.el6.x86_64 #1 SMP Wed Jun 13 18:24:36 EDT x86_64 x86_64 x86_64 GNU/Linux[xxx@www ~]$ cat /proc/versionLinux version 2.6.32-279.el6.x86_64 (mockbuild@x86-008.build.) (gcc version 4.4.6 0305 (Red Hat 4.4.6-4) (GCC) ) #1 SMP Wed Jun 13 18:24:36 EDT [xxx@www ~]$ cat /etc/issueRed Hat Enterprise Linux Server release 6.3 (Santiago)Kernel \r on an \m

2) Android客户端开发

操作系统:Windows 7 x86

测试环境: Android手机(系统4.0及以上)

开发工具和SDK包: adt-bundle-windows-x86-1030.zip(里面含有Eclipse)

本文所需软件如下:

android-ndk-r9c-linux-x86.tar.bz2 /intl/zh-cn/tools/sdk/ndk/index.htmladt-bundle-windows-x86-1030.zip /intl/zh-cn/sdk/index.htmlCode::Blocks /downloads/binaries

2. 环境搭建

1)Code::Blocks环境搭建

首先安装Code::Blocks, 然后解压 android-ndk-r9c-linux-x86.tar.bz2 , 如解压到桌面 /home/UserName/Desktop/android-ndk-r9c/

然后启动Code::Blocks, 进行系统环境配置

1.1) 配置全局环境

S1: 打开 Settings-> Compiler and debugger...

S2: 选择编译器Selected complier -> GNU ARM GCC Complier,或自己新建一个

S3: 选择 Toolchain executables

S4: 设置android-ndk路径( Complier's installation directory ) ,如/home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86

S5: 设置Program Files各个编译程序

C complier: arm-linux-androideabi-gcc

C++ compiler: arm-linux-androideabi-g++

Linker for dynamic libs: arm-linux-androideabi-g++

Linker for static libs: arm-linux-androideabi-ar

Debugger: arm-linux-androideabi-gdb

Resource compiler:

S6: 设置Additional Paths, 增加(Add) : /home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/arm-linux-androideabi/bin

S7: 设置 Search directories -> Compiler, 增加(Add) :/home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/include

S8: 设置 Search directories -> Linker,

[cpp]view plaincopy /home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/lib/home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/lib/gcc/arm-linux-androideabi/4.6/home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/lib/gcc/arm-linux-androideabi/4.6/armv7-a

S9: 设置完成,点击确定

1.2)配置项目的环境

S1: 右击项目,选择Build options, Selected Complier选择刚才设置的那个 GUN ARM GCC Compiler

S2: Compler settings -> Other options , 写入 -fPIC

S3: 设置 Search directories -> Linker, Add :

[cpp]view plaincopy /home/xxx/Desktop/android-ndk-r9c/platforms/android-14/arch-arm/usr/lib

S4: Search directories->Complier , Add

[java]view plaincopy /home/xxx/Desktop/android-ndk-r9c/platforms/android-14/arch-arm/usr/include

2)Android 开发环境搭建

直接解压adt-bundle-windows-x86-1030.zip , 如解压到 E:\Program Files\adt\adt-bundle-windows-x86-1030

就可以看到里面以及放好了eclipse, 此处的eclipse默认已经配置好了 adt, 启动 eclipse.exe 配置android虚拟机

菜单 Window -> Android Virtual Device Manager 管理虚拟机, Android SDK Manager 可以更新 SDK,由于此adt所带android系统是4.4, 建议再 更新 4.0.3 (

手动更新详见:手动下载Android开发SDK

sdk:platform ->https://dl-/android/repository/android-14_r03.zip

sdk:system-image ->https://dl-/android/repository/sysimg_armv7a-14_r02.zip

)

如下图所示

新建一个虚拟机

3. SO库编写

3.1)生成头文件

打开adt-bundle-windows里面的Eclipse

新建Android项目JniTestAndroid ,建立包 com.lpr, 建类 JniTestAndroid

JniTestAndroid.java

[java]view plaincopy packagecom.lpr;classJniTestAndroid{publicnativebyte[]recognition(bytearr[]);static{System.loadLibrary("AndroidCallsoDemo");//LoadAndroidCallsoDemo.soproducebycode::blocks//System.out.println(System.getProperty("java.library.path"));//System.setProperty("java.library.path",".");}}

用 Javac 编译成 class文件

>cd E:\JniTestAndroid>javac com/lpr/JniTestAndroid.java>javah com.lpr.JniTestAndroid

现在生成了com_lpr_JniTestAndroid.h[cpp]view plaincopy /*DONOTEDITTHISFILE-itismachinegenerated*/#include<jni.h>/*Headerforclasscom_lpr_JniTestAndroid*/#ifndef_Included_com_lpr_JniTestAndroid#define_Included_com_lpr_JniTestAndroid#ifdef__cplusplusextern"C"{#endif/**Class:com_lpr_JniTestAndroid*Method:recognition*Signature:([S)[B*/JNIEXPORTjbyteArrayJNICALLJava_com_lpr_JniTestAndroid_recognition(JNIEnv*,jobject,jbyteArray);#ifdef__cplusplus}#endif#endif

现在将com_lpr_JniTestAndroid.h拷贝到 Redhat 下面

并将 $java_home/include/jni.h 和 ./linux/jni_md.h 拷贝到 redhat 下面

在此特给出 jni_md.h 源码

[cpp]view plaincopy #ifndef_JAVASOFT_JNI_MD_H_#define_JAVASOFT_JNI_MD_H_#defineJNIEXPORT#defineJNIIMPORT#defineJNICALLtypedeflongjint;typedef__int64jlong;typedefsignedcharjbyte;#endif/*!_JAVASOFT_JNI_MD_H_*/

3.2)编写SO库

打开Code::Block新建(动态库)项目 AndroidCallsoDemo, 设置项目属性 参考上面的【 1.2 配置项目的环境】

添加 com_lpr_JniTestAndroid.h, jni.h, jni_md.h 到项目(不添加也可以,只要放到项目的更目录即可)

main.cpp

[cpp]view plaincopy #include"stdio.h"#include"com_lpr_JniTestAndroid.h"JNIEXPORTjbyteArrayJNICALLJava_com_lpr_JniTestAndroid_recognition(JNIEnv*jnienv,jobjectjobj,jbyteArraybyteArray){/*short*iArray;//=newshort[maxSize];jbooleanjbool=true;//转换数组iArray=jnienv->GetShortArrayElements(shortArray,&jbool);//...//jnienv->ReleaseShortArrayElements(shortArray,iArray,0);//dosomethingwithiArray...//carnumber;*/charcarnumber[64]={"你输入的是:"};jbyteArrayreturnLPRArray=jnienv->NewByteArray(64);jbyte*retbytes=jnienv->GetByteArrayElements(returnLPRArray,0);jbyte*bytes2=jnienv->GetByteArrayElements(byteArray,0);sprintf(carnumber,"%s%s",carnumber,bytes2);intnLPRLen=strlen(carnumber);//返回值最好是byte,以免utf8造成汉字的影响for(inti=0;i<nLPRLen;i++){retbytes[i]=carnumber[i];}jnienv->SetByteArrayRegion(returnLPRArray,0,nLPRLen,retbytes);returnreturnLPRArray;}

几点注意:

1. 如果传入参数或传出参数有汉字或比较复杂的结构,建议都化为 jbyteArray, 特别是有关的汉字问题

4. Android编写

建立android项目 JniTestAndroid

activity_karl.xml //

[html]view plaincopy <RelativeLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#F5F6F2"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".KarlActivity"><TextViewandroid:id="@+id/textView"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:text="result"android:textSize="20sp"/><Buttonandroid:id="@+id/button1"android:layout_width="match_parent"android:layout_height="40dp"android:layout_below="@+id/textView"android:gravity="center_horizontal"android:text="Button"/></RelativeLayout>

拷贝 com.lpr.JniTestAndroid 到项目 src 下面

karlActivity.java

[java]view plaincopy packagecom.karl.jnitestandroid;importandroid.os.Bundle;importandroid.app.Activity;importandroid.view.Menu;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.TextView;importcom.lpr.JniTestAndroid;publicclassKarlActivityextendsActivity{privateJniTestAndroidjni=newJniTestAndroid();privateButtonbt;privateTextViewtextView;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_karl);textView=(TextView)findViewById(R.id.textView);bt=(Button)findViewById(R.id.button1);bt.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewarg0){Stringstr="中国北京123ABC";bytedata[]=jni.recognition(str.getBytes());Stringtext=newString(data);//newString(data,"GB2312");textView.setText(text);}});}@OverridepublicbooleanonCreateOptionsMenu(Menumenu){//Inflatethemenu;thisaddsitemstotheactionbarifitispresent.getMenuInflater().inflate(R.menu.karl,menu);returntrue;}}

运行结果

5. 常见错误

5.1) ld: error: cannot open crtbegin_so.o: No such file or directory

[cpp]view plaincopy arm-linux-androideabi-g++-Wall-fexceptions-O2-fPIC-I../android-ndk-r9c/platforms/android-14/arch-arm/usr/include-cmain.cpp-oobj/Release/main.o/home/haifeng/android/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/as:/lib/libz.so.1:noversioninformationavailable(requiredby/home/haifeng/android/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/as)arm-linux-androideabi-g++-shared-L../android-ndk-r9c/platforms/android-14/arch-arm/usr/lib-L/home/haifeng/android/android-ndk-r9c/platforms/android-14/arch-arm/usr/libobj/Release/main.o-obin/Release/libAndroidCallsoDemo.so-s/home/haifeng/android/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld:error:cannotopencrtbegin_so.o:Nosuchfileordirectory/home/haifeng/android/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld:error:cannotopencrtend_so.o:Nosuchfileordirectorycollect2:ldreturned1exitstatus 原因是ld找不到 crtbegin_so.o 和 crteng_so.o, 解决方法是,在项目源码下面建立软连接

cd /home/xxx/android/AndroidCallsoDemo/ln -s /home/xxx/android/android-ndk-r9c/platforms/android-14/arch-arm/usr/lib/crtend_so.o ./ln -s /home/xxx/android/android-ndk-r9c/platforms/android-14/arch-arm/usr/lib/crtbegin_so.o ./

5.2) 查看SO库的依赖库

查看PC linux 平台是用 ldd, 查看嵌入式的用 arm-linx-*-readelf

[python]view plaincopy /home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-readelf-aAndroidCallsoDemo.so 或者

[python]view plaincopy /home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-readelf-aAndroidCallsoDemo.so|grep"Shared"

5.3) 使用STL

直接使用STL或用Opencv间接调用STL, 提示找不到 #include <algorithm> 等, 在工程的 Build Options -> Search directories -> Complier添加如下包含目录即可[python]view plaincopy /home/xxx/Desktop/android-ndk-r9c/sources/cxx-stl/gnu-libstdc++/4.6/include[plain]view plaincopy /home/xxx/Desktop/android-ndk-r9c/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。