CC++在JavaAndroid與ObjectiveC三大平臺下實現(xiàn)混合編程_第1頁
CC++在JavaAndroid與ObjectiveC三大平臺下實現(xiàn)混合編程_第2頁
CC++在JavaAndroid與ObjectiveC三大平臺下實現(xiàn)混合編程_第3頁
CC++在JavaAndroid與ObjectiveC三大平臺下實現(xiàn)混合編程_第4頁
CC++在JavaAndroid與ObjectiveC三大平臺下實現(xiàn)混合編程_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Android和iOS開發(fā)都支持C+開發(fā),可以一套代碼多平臺使用。同時C+難以反編譯的特性也可以為Android開發(fā)帶來代碼的保密,另一native特性也可以提高代碼的運行效率。一、為什么使用C/C+1. 便于移植,用C/C+寫得庫可以方便在其他的平臺上再次使用。2. 代碼的保護,由于java層代碼很容易被反編譯,而C/C+庫反匯難度較大。3. 提高程序的執(zhí)行效率,將要求高性能的應(yīng)用邏輯使用C/C+開發(fā),從而提高應(yīng)用程序的執(zhí)行效率。4. 訪問現(xiàn)有開源庫,需要訪問底層的API或引用一些只有C/C+的庫。二、開發(fā)工具介紹盡管Android Studio可以同時編寫C+和Java代碼,寫完就可以編譯

2、運行,但是對聯(lián)想和錯誤提示并不是非常友好,個人建議C+的整體代碼使用Visual Studio或Xcode編譯開發(fā),聯(lián)想功能非常友好,編譯速度很快,調(diào)試也非常方便。 Visual Studio(PC) Xcode(Mac) Android Studio(多平臺) eclipse(多平臺)三、第一行代碼1. 如何在Objective-C項目中使用C+;在Objective-C使用C/C+非常簡單,僅僅需要把.m后綴的文件改成.mm即可使用C+,我們通常不會把.mm的文件寫到整個項目都有,而是設(shè)計一個接口,用來做兩個語言之間的橋梁,他們之間的交互僅僅在這個接口。要點:String類型轉(zhuǎn)換/ Obj

3、ective-C(NSString) - C+(std:string)NSString * ocString = Hello World,OC;std:string cppString = ocString UTF8String;std:coutcppString Objective-C(NSString)std:string cppString2 = Hello World,C+;NSString *ocString2= NSString stringWithCString:cppString2.c_str() encoding:NSString defaultCStringEncoding

4、;NSLog(%,ocString2);記得要include相關(guān)的文件#include #include 2.在普通的JAVA項目中使用JNI編程由于我是在MAC下辦公,所以這里就介紹如何在MAC下進行JNI開發(fā),在Windows平臺下的Virtual Studio也很簡單。第一步:在Xcode下創(chuàng)建一個普通的C+項目第二步:關(guān)聯(lián)JavaVM的Framework路徑:/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaNativeFoundation.framework/第三步:創(chuàng)建頭文件,用于和Java交互 cn_taowei

5、ji_nativemodule_NativeDemo.h#include #ifndef _Included_cn_taoweiji_nativemodule_NativeDemo#define _Included_cn_taoweiji_nativemodule_NativeDemo#ifdef _cplusplusextern C #endif JNIEXPORT jint JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_add (JNIEnv *, jclass, jint, jint); JNIEXPORT void JNICALL J

6、ava_cn_taoweiji_nativemodule_NativeDemo_say (JNIEnv *, jclass, jstring); JNIEXPORT jstring JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_getInfo (JNIEnv *, jclass); JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_nativeToJava (JNIEnv *, jclass, jobject);#ifdef _cplusplus#endif#end

7、if第四步:創(chuàng)建實現(xiàn) NativeDemo.cpp#include cn_taoweiji_nativemodule_NativeDemo.h#include JNIEXPORT jint JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_add(JNIEnv *, jclass, jint param1, jint param2) jint result = param1 + param2; return result;JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo

8、_say(JNIEnv *env, jclass, jstring param) / std:string - jstring const char *param_char = env-GetStringUTFChars(param, NULL); std:string str = param_char;JNIEXPORT jstring JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_getInfo(JNIEnv *env, jclass) / jstring - std:string std:string str = Hi,I am C+.

9、; jstring result = env-NewStringUTF(str.c_str(); return result;JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_nativeToJava(JNIEnv * env, jclass, jobject obj) / 調(diào)用Java方法 jclass cls = env-FindClass(cn/taoweiji/nativemodule/NativeDemo); /int subtract(int , int param2) - (II)I jmethodID

10、 mid = env-GetMethodID(cls, subtract, (II)I); int result = (int) env-CallIntMethod(obj, mid, 10, 2);/ std:coutresult ()Ljava/lang/String; /PackageInfo getPackageInfo(String packageName, int flags); /- (Ljava/lang/String;I)Landroid/content/pm/PackageInfo;第五步:編譯生成JNI文件,按 +B (Product - Build).編譯后文件根據(jù)自己

11、的電腦環(huán)境,查找編譯后的文件,我的路徑是/Users/Wiki/Library/Developer/Xcode/DerivedData/DEMO_MAC_JNI-clxymnzifegyfaajsaattzgxqfbr/Build/Products/Debug/DEMO_MAC_JNI第六步:編寫JNI接口package cn.taoweiji.nativemodule;/* * 包名和類名稱一定要和前面的C+頭文件對應(yīng) * cn_taoweiji_nativemodule_NativeDemo.h */public class NativeDemo public static native

12、int add(int param1, int param2); public static native void say(String name); public static native String getInfo(); public static native void nativeToJava(NativeDemo nativeDemo); public int subtract(int param1, int param2) System.out.println(NativeDemo: + String.format(%s - %s = %s, param1, param2,

13、param1 - param2); return param1 - param2; 第七步:調(diào)用C+public class Main static System.load(/Users/Wiki/Library/Developer/Xcode/DerivedData/DEMO_MAC_JNI-clxymnzifegyfaajsaattzgxqfbr/Build/Products/Debug/DEMO_MAC_JNI); public static void main(String args) System.out.println(Hello World!); int result = Nat

14、iveDemo.add(1, 2); System.out.println(1+2= + String.valueOf(result); NativeDemo.say(Hello,I am Java.); System.out.println(getInfo: + NativeDemo.getInfo(); NativeDemo.nativeToJava(new NativeDemo(); 3. 在ANDROID項目中使用NDKAndroid的JNI開發(fā),C+文件必須編寫在獨立的module里面,Java接口代碼可以編寫在app(module),也可以和C+放在同一個module,通過grad

15、le關(guān)聯(lián)。詳細代碼請自行下載demo瀏覽gradle配置(NativeModule)apply plugin: com.android.libraryandroid compileSdkVersion 23 buildToolsVersion 24.0.0 rc2 defaultConfig minSdkVersion 14 targetSdkVersion 23 versionCode 1 versionName 1.0 buildTypes release minifyEnabled false proguardFiles getDefaultProguardFile(proguard-a

16、ndroid.txt), ndk moduleName joyrun stl stlport_static ldLibs log/用于解決_android_log_print abiFilters armeabi, armeabi-v7a, x86, x86_64, arm64-v8a /add -fexceptions to allow throw error /add -w to format not a string literal and no format arguments -Werror=format-security cFlags -w -

17、fexceptions dependencies compile fileTree(dir: libs, include: *.jar)編寫JNI接口/ NativeDemo.javapackage cn.taoweiji.nativemodule;public class NativeDemo public static native int add(int param1, int param2);編寫C+接口代碼,JNI文件目錄默認是module/src/main/jni,可以通過gradle配置改變/ cn_taoweiji_nativemodule_NativeDemo.h#inclu

18、de #ifndef _Included_cn_taoweiji_nativemodule_NativeDemo#define _Included_cn_taoweiji_nativemodule_NativeDemo#ifdef _cplusplusextern C #endif/* * Class: cn_taoweiji_nativemodule_NativeDemo * Method: add * Signature: (II)I */JNIEXPORT jint JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_add(JNIEnv *

19、, jclass, jint, jint);#ifdef _cplusplus#endif#endif/ NativeDemo.cpp#include cn_taoweiji_nativemodule_NativeDemo.hJNIEXPORT jint JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_add(JNIEnv *, jclass, jint param1, jint param2) jint result = param1 + param2; return result;調(diào)用/ 靜態(tài)加載static System.loadLibr

20、ary(joyrun);/調(diào)用int result = NativeDemo.add(1,2);Log.i(1+2=,String.valueOf(result);四、NDK開發(fā)要點編譯文件分析將NativeModule編譯后生成的aar文件后綴改成.zip解壓,可以發(fā)現(xiàn)里面有個jni文件,打開可以看到”armeabi”, “armeabi-v7a”, “x86”, “x86_64”, “arm64-v8a”等文件夾,再打開可以看到是以lib前綴的so格式文件,這就是編譯后的native層文件,我們平常引用的第三方庫(百度地圖)也是要添加這些文件到我們的libs文件夾,不同的名稱代表著不同平臺

21、相關(guān)的編譯文件,市面上大多數(shù)的手機都是arm架構(gòu)CPU,x86架構(gòu)的手機幾乎沒人用(genymotion模擬器屬于x86平臺),所以我們通常發(fā)布APP不會考慮x86平臺,僅僅添加armeabi文件即可,但是在開發(fā)過程中建議也添加x86的so文件,以方便我們在模擬器上運行。運行庫Android平臺帶有一個微型的C運行庫支持庫,成為系統(tǒng)運行庫。該運行庫不支持一下特性:C標準庫、異常支持、RTTI支持。NDK提供了用于補充系統(tǒng)運行庫功能的一些額外的C+運行庫。C+運行庫C+異常支持C+RTTIC+標準庫系統(tǒng)庫NoNoNoGAbi+NoYesNoSTLportNoYesYesGNU STLYesYes

22、Yes1. STLportSTLport是一個開源的、多平臺的C標準庫實現(xiàn)。它提供一個C標準庫頭文件的完整集合以及對RTTI的支持。2. GNU STLGNU標準C庫,也叫l(wèi)ibstdc-v3,是Android NDK最全面的標準C運行庫。它是一個正在開發(fā)的、以實現(xiàn)ISO標準C庫為目標的開源項目。gradle配置1. STL運行庫引用2. “armeabi”, “armeabi-v7a”, “x86”, “x86_64”, “arm64-v8a”等平臺配置3. C+輸出logcat配置4. 一個編譯異常解決5. 異常捕獲6. / 生成so文件的名稱7. moduleName joyrun8.

23、/ 引入STL標準庫9. stl stlport_static/gnustl_static10. /用于解決_android_log_print11. ldLibs log12. abiFilters armeabi, armeabi-v7a, x86, x86_64, arm64-v8a /添加編譯的平臺13. /add -fexceptions to allow throw error14. /add -w to format not a string literal and no format arguments -Werror=format-securitycFlags -w -fex

24、ceptionsLOGCAT輸出#include #define LOGI(.) _android_log_print(ANDROID_LOG_INFO, tag_joyrun, _VA_ARGS_)#define LOGE(.) _android_log_print(ANDROID_LOG_ERROR, tag_joyrun, _VA_ARGS_)LOGE(Hello Logcat);類型轉(zhuǎn)換/ std:string - jstringstd:string str = Hello World;jstring result = env-NewStringUTF(str.c_str();/ js

25、tring - std:stringjstring param;const char *param_char = env-GetStringUTFChars(param, NULL);std:string str = param_char;/ jboolean 兩個值 JNI_TRUE、JNI_FALSEC+調(diào)用JAVA代碼/Javapublic static native void nativeToJava(NativeDemo nativeDemo);public int subtract(int param1, int param2) Log.e(NativeDemo, String.f

26、ormat(%s - %s = %s, param1, param2, param1 - param2);return param1 - param2;/C+JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_nativeToJava(JNIEnv * env, jclass, jobject obj) / 調(diào)用Java方法 jclass cls = env-FindClass(cn/taoweiji/nativemodule/NativeDemo); jmethodID mid = env-GetMethodID(c

27、ls, subtract, (II)I); int result = (int) env-CallIntMethod(obj, mid, 10, 2); /常見類型轉(zhuǎn)換例子 /String getInfo(); /- ()Ljava/lang/String; /PackageInfo getPackageInfo(String packageName, int flags); /- (Ljava/lang/String;I)Landroid/content/pm/PackageInfo;一鍵生成從JAVA到C+接口代碼腳本文件:autojavah.sh#!/bin/shexport Proje

28、ctPath=$(cd ./$(dirname $1); pwd)export TargetClassName=co.runner.app.jni.NativeDemoexport SourceFile=$ProjectPath/app/src/main/javaexport TargetPath=$ProjectPath/jni-joyrun/src/main/jnicd $SourceFilejavah -d $TargetPath -classpath $SourceFile $TargetClassNameecho -d $TargetPath -classpath $SourceFi

29、le $TargetClassName五、C+面向?qū)ο蠹皹藴蕩烊腴TC+類定義/ Demo.hpp#ifndef Demo_hpp#define Demo_hpp#include #include class Demopublic: std:string name; int age = 0; void say(); static int add(int param1,int param2) return param1 + param2; ;#endif /* Demo_hpp */類方法的實現(xiàn)/ Demo.cpp#include Demo.hpp#include void Demo:say() std:coutname = name,age = agesay();/靜態(tài)函數(shù)訪問int result = Demo:add(1,2);std:cout1 + 2 = resultstd:endl;LIST鏈表/include相關(guān)文件#include #include #include #include Demo.hpp/

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論