Android調(diào)用so庫, so庫是c語言編寫, 在linux 64位系統(tǒng)+ndk(32位)生成 lib*.so (32位)
1. 所需軟件環(huán)境: 1)so庫開發(fā)環(huán)境 操作系統(tǒng): Redhat Server 6.3 ?x86_64
編譯軟件:Code::Blocks
Android native開發(fā)庫: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 \r on an \m
?
2) Android客戶端開發(fā) 操作系統(tǒng):Windows 7 x86
測試環(huán)境: Android手機(jī)(系統(tǒng)4.0及以上)
開發(fā)工具和SDK包: adt-bundle-windows-x86-20131030.zip(里面含有Eclipse)
本文所需軟件如下:
android-ndk-r9c-linux-x86.tar.bz2 ??http://developer.android.com/intl/zh-cn/tools/sdk/ndk/index.html adt-bundle-windows-x86-20131030.zip ??http://developer.android.com/intl/zh-cn/sdk/index.html Code::Blocks ?http://www.codeblocks.org/downloads/binaries ?
2. 環(huán)境搭建 1)Code::Blocks環(huán)境搭建 ? ? ? 首先安裝Code::Blocks, 然后解壓 android-ndk-r9c-linux-x86.tar.bz2 , 如解壓到桌面 ?/home/UserName/Desktop/android-ndk-r9c/ ? ? ? 然后啟動Code::Blocks, ?進(jìn)行系統(tǒng)環(huán)境配置
? ? ?1.1) 配置全局環(huán)境
? ? ? ? ? ?S1: ?打開 ?Settings-> Compiler and debugger...?
? ? ? ? ? ?S2: ?選擇編譯器Selected complier -> ?GNU ARM GCC Complier,或自己新建一個
? ? ? ? ? ?S3: ?選擇 Toolchain executables
? ? ? ? ? ?S4: ?設(shè)置android-ndk路徑( Complier's installation directory ) ,如?/home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86
? ? ? ? ? ?S5: ?設(shè)置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: 設(shè)置Additional Paths, ?增加(Add) ?: ?/home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/arm-linux-androideabi/bin
? ? ? ? ? ?S7: 設(shè)置 Search directories -> Compiler, ?增加(Add) ?:?/home/xxx/Desktop/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/include
? ? ? ? ? ?S8: 設(shè)置 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: ?設(shè)置完成,點(diǎn)擊確定
? ? 1.2)?配置項(xiàng)目的環(huán)境
? ? ? ? ?S1: ?右擊項(xiàng)目,選擇Build options, ?Selected Complier選擇剛才設(shè)置的那個 ?GUN ARM GCC Compiler?
? ? ? ? ?S2: ?Compler settings -> Other options , 寫入 ?-fPIC
? ? ? ? ?S3: ?設(shè)置 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 開發(fā)環(huán)境搭建
? ? ?直接解壓?adt-bundle-windows-x86-20131030.zip , 如解壓到 ?E:\Program Files\adt\adt-bundle-windows-x86-20131030?
? ? ?
? ? ?就可以看到里面以及放好了eclipse, 此處的eclipse默認(rèn)已經(jīng)配置好了 adt, ?啟動 eclipse.exe 配置android虛擬機(jī)
? ? 菜單 Window -> Android Virtual Device Manager ?管理虛擬機(jī), Android SDK Manager 可以更新 SDK,由于此adt所帶android系統(tǒng)是4.4, ?建議再 更新 4.0.3 (
? ? ? ? ? ?手動更新詳見:?手動下載Android開發(fā)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?? ? ? ?)
? ? 如下圖所示
? ??
? ? 新建一個虛擬機(jī)
? ??
3. SO庫編寫 ? ? 3.1)生成頭文件 ? ? ? ? 打開adt-bundle-windows里面的Eclipse
? ? ? ? 新建Android項(xiàng)目JniTestAndroid ,建立包 com.lpr, 建類 ?JniTestAndroid
? ? ? ? JniTestAndroid.java
[java] ?view plaincopy
package?com.lpr;?? class?JniTestAndroid?{?? ????public?native?byte[]??recognition(byte?arr[]);?? ??????static?{?? ????System.loadLibrary("AndroidCallsoDemo"); ???? ???? ??????}?? }?? ?用 Javac 編譯成 class文件 >cd E:\JniTestAndroid
>javac com/lpr/JniTestAndroid.java
>javah com.lpr.JniTestAndroid
現(xiàn)在生成了?com_lpr_JniTestAndroid.h
[cpp] ?view plaincopy
#include?<jni.h>?? ?? #ifndef?_Included_com_lpr_JniTestAndroid?? #define?_Included_com_lpr_JniTestAndroid?? #ifdef?__cplusplus?? extern?"C"?{?? #endif?? JNIEXPORT?jbyteArray?JNICALL?Java_com_lpr_JniTestAndroid_recognition?? ??(JNIEnv?*,?jobject,?jbyteArray);?? ?? #ifdef?__cplusplus?? }?? #endif?? #endif?? 現(xiàn)在將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_?? ?? #define?JNIEXPORT?? #define?JNIIMPORT?? #define?JNICALL??? ?? typedef?long?jint;?? typedef?__int64?jlong;?? typedef?signed?char?jbyte;?? ?? #endif?/*?!_JAVASOFT_JNI_MD_H_?*/?? ?
? ? ? 3.2)編寫SO庫 ? ? ? ? ? ? ?打開Code::Block新建(動態(tài)庫)項(xiàng)目 AndroidCallsoDemo, 設(shè)置項(xiàng)目屬性 ?參考上面的【 1.2? 配置項(xiàng)目的環(huán)境】
? ? ? ? ? ? ?添加 com_lpr_JniTestAndroid.h, jni.h, ?jni_md.h 到項(xiàng)目(不添加也可以,只要放到項(xiàng)目的更目錄即可)
? ? ? ? ? ? main.cpp
?
[cpp] ?view plaincopy
#include?"stdio.h"?? #include?"com_lpr_JniTestAndroid.h"?? ?? JNIEXPORT?jbyteArray?JNICALL?Java_com_lpr_JniTestAndroid_recognition?? (JNIEnv?*jnienv,?jobject?jobj,?jbyteArray?byteArray)?? {?? ???? ????char?carnumber[64]=?{"你輸入的是:"};?? ?? ????jbyteArray??returnLPRArray?=?jnienv->NewByteArray(?64?);?? ????jbyte?*retbytes?=?jnienv->GetByteArrayElements(?returnLPRArray,?0);?? ?? ????jbyte?*bytes2?=?jnienv->GetByteArrayElements(byteArray,?0);?? ?? ????sprintf(carnumber,?"%s?%s",carnumber,?bytes2);?? ?? ????int?nLPRLen?=?strlen(carnumber);?? ???? ????for?(?int?i?=?0;?i?<?nLPRLen;??i++?)?? ????{?? ????????retbytes[?i?]?=?carnumber[?i?];?? ????}?? ?? ????jnienv->SetByteArrayRegion(returnLPRArray,?0,?nLPRLen,?retbytes?);?? ?? ????return???returnLPRArray?;?? }?? ?
? ? ? ? ? ??
? ? ? ? ? ?幾點(diǎn)注意:
? ? ? ? ? ? 1. 如果傳入?yún)?shù)或傳出參數(shù)有漢字或比較復(fù)雜的結(jié)構(gòu),建議都化為 jbyteArray, 特別是有關(guān)的漢字問題
?
4. Android編寫 ? 建立android項(xiàng)目 JniTestAndroid
? activity_karl.xml //?
?
[html] ?view plaincopy
<RelativeLayout?xmlns:android="http://schemas.android.com/apk/res/android"?? ????xmlns:tools="http://schemas.android.com/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"?>?? ?? ????<TextView?? ????????android:id="@+id/textView"?? ????????android:layout_width="match_parent"?? ????????android:layout_height="wrap_content"?? ????????android:gravity="center_horizontal"?? ????????android:text="result"?? ????????android:textSize="20sp"?/>?? ?? ?? ????<Button?? ????????android: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 ?到項(xiàng)目 src 下面
?
karlActivity.java
?
[java] ?view plaincopy
package?com.karl.jnitestandroid;?? ?? import?android.os.Bundle;?? import?android.app.Activity;?? import?android.view.Menu;?? import?android.view.View;?? import?android.view.View.OnClickListener;?? import?android.widget.Button;?? import?android.widget.TextView;?? ?? import?com.lpr.JniTestAndroid;?? ?? public?class?KarlActivity?extends?Activity?{?? ?? ????private?JniTestAndroid?jni?=?new?JniTestAndroid();?? ????private?Button?bt;?? ????private?TextView?textView;?? ????@Override?? ????protected?void?onCreate(Bundle?savedInstanceState)?{?? ????????super.onCreate(savedInstanceState);?? ????????setContentView(R.layout.activity_karl);?? ?????????? ????????textView?=?(TextView)findViewById(R.id.textView);???? ????????bt?=?(Button)?findViewById(R.id.button1);???? ????????bt.setOnClickListener(new?OnClickListener(){?? ?? ????????????@Override?? ????????????public?void?onClick(View?arg0)?{?? ????????????????String?str="中國北京123ABC";?? ????????????????byte?data[]?=??jni.recognition(str.getBytes());?? ????????????????String?text?=?new?String(data);? ????????????????textView.setText(text);?? ????????????}?? ????????});?? ????}?? ?? ????@Override?? ????public?boolean?onCreateOptionsMenu(Menu?menu)?{?? ???????? ????????getMenuInflater().inflate(R.menu.karl,?menu);?? ????????return?true;?? ????}?? ?? }?? 運(yùn)行結(jié)果
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??-c?main.cpp?-o?obj/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:?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)?? 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???? /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?? /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?? collect2:?ld?returned?1?exit?status?? 原因是ld找不到 ?crtbegin_so.o 和 crteng_so.o, 解決方法是,在項(xiàng)目源碼下面建立軟連接
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?-a?AndroidCallsoDemo.so?? 或者
[python] ?view plaincopy
/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間接調(diào)用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 ?
轉(zhuǎn)載于:https://www.cnblogs.com/forbeat/p/5001141.html
總結(jié)
以上是生活随笔 為你收集整理的linux android ndk 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。