• linux android ndk


    1. 所需软件环境:

    1)so库开发环境

    操作系统: Redhat Server 6.3  x86_64

    编译软件:Code::Blocks

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

    [xxx@www ~]$ uname -a
    Linux www.teleframe.cn 2.6.32-279.el6.x86_64 #1 SMP Wed Jun 13 18:24:36 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux
    [xxx@www ~]$ cat /proc/version
    Linux version 2.6.32-279.el6.x86_64 (mockbuild@x86-008.build.bos.redhat.com) (gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC) ) #1 SMP Wed Jun 13 18:24:36 EDT 2012
    [xxx@www ~]$ cat /etc/issue
    Red Hat Enterprise Linux Server release 6.3 (Santiago)
    Kernel 
     on an m

    2) Android客户端开发

    操作系统:Windows 7 x86

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

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

    本文所需软件如下:

    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在CODE上查看代码片派生到我的代码片
     
    1. /home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/lib  
    2. /home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/lib/gcc/arm-linux-androideabi/4.6  
    3. /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在CODE上查看代码片派生到我的代码片
     
    1. /home/xxx/Desktop/android-ndk-r9c/platforms/android-14/arch-arm/usr/lib  

            S4: Search directories->Complier , Add 

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /home/xxx/Desktop/android-ndk-r9c/platforms/android-14/arch-arm/usr/include  

    2)Android 开发环境搭建

         直接解压 adt-bundle-windows-x86-20131030.zip , 如解压到  E:Program Filesadtadt-bundle-windows-x86-20131030 

         

         就可以看到里面以及放好了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-ssl.google.com/android/repository/android-14_r03.zip
                     sdk:system-image -> https://dl-ssl.google.com/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在CODE上查看代码片派生到我的代码片
     
    1. package com.lpr;  
    2. class JniTestAndroid {  
    3.     public native byte[]  recognition(byte arr[]);  
    4.       static {  
    5.     System.loadLibrary("AndroidCallsoDemo");//Load  AndroidCallsoDemo.so produce by code::blocks  
    6.     //  System.out.println(System.getProperty("java.library.path"));  
    7.     //  System.setProperty("java.library.path", ".");  
    8.       }  
    9. }  

     用 Javac 编译成 class文件
    >cd E:JniTestAndroid
    >javac com/lpr/JniTestAndroid.java
    >javah com.lpr.JniTestAndroid
    
    现在生成了 com_lpr_JniTestAndroid.h
    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /* DO NOT EDIT THIS FILE - it is machine generated */  
    2. #include <jni.h>  
    3. /* Header for class com_lpr_JniTestAndroid */  
    4.   
    5. #ifndef _Included_com_lpr_JniTestAndroid  
    6. #define _Included_com_lpr_JniTestAndroid  
    7. #ifdef __cplusplus  
    8. extern "C" {  
    9. #endif  
    10. /* 
    11.  * Class:     com_lpr_JniTestAndroid 
    12.  * Method:    recognition 
    13.  * Signature: ([S)[B 
    14.  */  
    15. JNIEXPORT jbyteArray JNICALL Java_com_lpr_JniTestAndroid_recognition  
    16.   (JNIEnv *, jobject, jbyteArray);  
    17.   
    18. #ifdef __cplusplus  
    19. }  
    20. #endif  
    21. #endif  

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

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

    在此特给出 jni_md.h 源码

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #ifndef _JAVASOFT_JNI_MD_H_  
    2. #define _JAVASOFT_JNI_MD_H_  
    3.   
    4. #define JNIEXPORT  
    5. #define JNIIMPORT  
    6. #define JNICALL   
    7.   
    8. typedef long jint;  
    9. typedef __int64 jlong;  
    10. typedef signed char jbyte;  
    11.   
    12. #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在CODE上查看代码片派生到我的代码片
     
    1. #include "stdio.h"  
    2. #include "com_lpr_JniTestAndroid.h"  
    3.   
    4. JNIEXPORT jbyteArray JNICALL Java_com_lpr_JniTestAndroid_recognition  
    5. (JNIEnv *jnienv, jobject jobj, jbyteArray byteArray)  
    6. {  
    7.     /*    short*  iArray ; //=new short[maxSize]; 
    8.         jboolean jbool = true; 
    9.         //转换数组 
    10.         iArray = jnienv->GetShortArrayElements(shortArray, &jbool); 
    11.         //... 
    12.         // 
    13.         jnienv->ReleaseShortArrayElements(shortArray,iArray,0); 
    14.         // do something with iArray ... 
    15.  
    16.  
    17.         // carnumber; 
    18.     */  
    19.     char carnumber[64]= {"你输入的是:"};  
    20.   
    21.     jbyteArray  returnLPRArray = jnienv->NewByteArray( 64 );  
    22.     jbyte *retbytes = jnienv->GetByteArrayElements( returnLPRArray, 0);  
    23.   
    24.     jbyte *bytes2 = jnienv->GetByteArrayElements(byteArray, 0);  
    25.   
    26.     sprintf(carnumber, "%s %s",carnumber, bytes2);  
    27.   
    28.     int nLPRLen = strlen(carnumber);  
    29.     //返回值最好是 byte,以免utf8造成汉字的影响  
    30.     for ( int i = 0; i < nLPRLen;  i++ )  
    31.     {  
    32.         retbytes[ i ] = carnumber[ i ];  
    33.     }  
    34.   
    35.     jnienv->SetByteArrayRegion(returnLPRArray, 0, nLPRLen, retbytes );  
    36.   
    37.     return   returnLPRArray ;  
    38. }  

                

               几点注意:

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

    4. Android编写

      建立android项目 JniTestAndroid

      activity_karl.xml // 

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     xmlns:tools="http://schemas.android.com/tools"  
    3.     android:layout_width="match_parent"  
    4.     android:layout_height="match_parent"  
    5.     android:background="#F5F6F2"  
    6.     android:paddingBottom="@dimen/activity_vertical_margin"  
    7.     android:paddingLeft="@dimen/activity_horizontal_margin"  
    8.     android:paddingRight="@dimen/activity_horizontal_margin"  
    9.     android:paddingTop="@dimen/activity_vertical_margin"  
    10.     tools:context=".KarlActivity" >  
    11.   
    12.     <TextView  
    13.         android:id="@+id/textView"  
    14.         android:layout_width="match_parent"  
    15.         android:layout_height="wrap_content"  
    16.         android:gravity="center_horizontal"  
    17.         android:text="result"  
    18.         android:textSize="20sp" />  
    19.   
    20.   
    21.     <Button  
    22.         android:id="@+id/button1"  
    23.         android:layout_width="match_parent"  
    24.         android:layout_height="40dp"  
    25.         android:layout_below="@+id/textView"  
    26.         android:gravity="center_horizontal"  
    27.         android:text="Button" />  
    28.   
    29. </RelativeLayout>  

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

    karlActivity.java

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. package com.karl.jnitestandroid;  
    2.   
    3. import android.os.Bundle;  
    4. import android.app.Activity;  
    5. import android.view.Menu;  
    6. import android.view.View;  
    7. import android.view.View.OnClickListener;  
    8. import android.widget.Button;  
    9. import android.widget.TextView;  
    10.   
    11. import com.lpr.JniTestAndroid;  
    12.   
    13. public class KarlActivity extends Activity {  
    14.   
    15.     private JniTestAndroid jni = new JniTestAndroid();  
    16.     private Button bt;  
    17.     private TextView textView;  
    18.     @Override  
    19.     protected void onCreate(Bundle savedInstanceState) {  
    20.         super.onCreate(savedInstanceState);  
    21.         setContentView(R.layout.activity_karl);  
    22.           
    23.         textView = (TextView)findViewById(R.id.textView);    
    24.         bt = (Button) findViewById(R.id.button1);    
    25.         bt.setOnClickListener(new OnClickListener(){  
    26.   
    27.             @Override  
    28.             public void onClick(View arg0) {  
    29.                 String str="中国北京123ABC";  
    30.                 byte data[] =  jni.recognition(str.getBytes());  
    31.                 String text = new String(data); //new String(data, "GB2312");  
    32.                 textView.setText(text);  
    33.             }  
    34.         });  
    35.     }  
    36.   
    37.     @Override  
    38.     public boolean onCreateOptionsMenu(Menu menu) {  
    39.         // Inflate the menu; this adds items to the action bar if it is present.  
    40.         getMenuInflater().inflate(R.menu.karl, menu);  
    41.         return true;  
    42.     }  
    43.   
    44. }  

    运行结果

    5.  常见错误

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

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. arm-linux-androideabi-g++ -Wall -fexceptions  -O2 -fPIC    -I../android-ndk-r9c/platforms/android-14/arch-arm/usr/include  -c main.cpp -o obj/Release/main.o  
    2. /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: no version information available (required by /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)  
    3. 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/lib  obj/Release/main.o   -o bin/Release/libAndroidCallsoDemo.so -s    
    4. /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: cannot open crtbegin_so.o: No such file or directory  
    5. /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: cannot open crtend_so.o: No such file or directory  
    6. collect2: ld returned 1 exit status  
     
    原因是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在CODE上查看代码片派生到我的代码片
     
    1. /home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-readelf -a AndroidCallsoDemo.so  
    或者
    [python] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-readelf -a AndroidCallsoDemo.so | grep "Shared"  

       5.3) 使用STL
       直接使用STL或用Opencv间接调用STL, 提示找不到  #include <algorithm> 等,  在工程的 Build Options ->  Search directories -> Complier添加如下包含目录即可
    [python] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /home/xxx/Desktop/android-ndk-r9c/sources/cxx-stl/gnu-libstdc++/4.6/include  
    [plain] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /home/xxx/Desktop/android-ndk-r9c/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include  
  • 相关阅读:
    Non-local Neural Networks
    BERT-related Papers
    BERT在多模态领域中的应用
    Learning When and Where to Zoom with Deep Reinforcement Learning
    Physical Adversarial Textures That Fool Visual Object Tracking
    Deep Neural Networks are Easily Fooled: High Confidence Predictions for Unrecognizable Images
    Tutorial on Adversarial Example Generation
    NeurIPS 2019: Computer Vision Recap
    Deep Learning for Time Series Classification (InceptionTime)
    Contrastive Self-Supervised Learning
  • 原文地址:https://www.cnblogs.com/forbeat/p/5001141.html
Copyright © 2020-2023  润新知