




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android和iOS开发都支持C++开发,可以一套代码多平台使用。同时C++难以反编译的特性也可以为Android开发带来代码的保密,另一native特性也可以提高代码的运行效率。一、为什么使用C/C++便于移植,用C/C++写得库可以方便在其他的平台上再次使用。代码的保护,由于java层代码很容易被反编译,而C/C++库反汇难度较大。提高程序的执行效率,将要求高性能的应用逻辑使用C/C++开发,从而提高应用程序的执行效率。访问现有开源库,需要访问底层的API或引用一些只有C/C++的库。二、开发工具介绍尽管AndroidStudio可以同时编写C++和Java代码,写完就可以编译运行,但是对联想和错误提示并不是非常友好,个人建议C++的整体代码使用VisualStudio或Xcode编译开发,联想功能非常友好,编译速度很快,调试也非常方便。VisualStudio(PC)Xcode(Mac)AndroidStudio(多平台)eclipse(多平台)三、第一行代码1.如何在Objective-C项目中使用C++;在Objective-C使用C/C++非常简单,仅仅需要把m后缀的文件改成.mm即可使用C++,我们通常不会把.mm的文件写到整个项目都有,而是设计一个接口,用来做两个语言之间的桥梁,他们之间的交互仅仅在这个接口。要点:String类型转换//Objective-C(NSString)->C++(std::string)NSString*ocString="HelloWorld,OC";std::stringcppString=[ocStringUTF8String];std::cout<<cppString<<std::endl;//C++(std::string)->Objective-C(NSString)std::stringcppString2="HelloWorld,C++";NSString*ocString2=[NSStringstringWithCString:cppString2.c_str()encoding:[NSStringdefaultCStringEncoding]];NSLog(@"%@",ocString2);记得要include相关的文件#include<stdio.h>#include<iostream>2.在普通的JAVA项目中使用JNI编程由于我是在MAC下办公,所以这里就介绍如何在MAC下进行JNI开发,在Windows平台下的VirtualStudio也很简单。第一步:在Xcode下创建一个普通的。++项目第二步:关联JavaVM的Framework路径:/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaNativeFoundation.framework/第三步:创建头文件,用于和Java交互cn_taoweiji_nativemodule_NativeDemo.h#include<JavaVM/jni.h>#ifndef_Included_cn_taoweiji_nativemodule_NativeDemo#define_Included_cn_taoweiji_nativemodule_NativeDemo#ifdefcplusplusextern"C"{#endifJNIEXPORTjintJNICALLJava_cn_taoweiji_nativemodule_NativeDemq_add(JNIEnv*,jclass,jint,jint);JNIEXPORTvoidJNICALLJava_cn_taoweiji_nativemodule_NativeDemq_say(JNIEnv*,jclass,jstring);JNIEXPORTjstringJNICALLJava_cn_taoweiji_nativemodule^ativeDemo_getlnfo(JNIEnv*,jclass);JNIEXPORTvoidJNICALLJavEcn_taoweiji_nativemodule^ativeDemojnativeToJava(JNIEnv*,jclass,jobject);#ifdefcplusplus}#endif#endif第四步:创建实现NativeDemo.cpp#include^cn_taoweiji_nativemqdule_NativeDemq.h^#include<string>JNIEXPORTjintJNICALLJava_cn_taoweiji_nativemqdule_NativeDemq_add(JNIEnv*,jclass,jintparam1,jintparam2){jintresult=param1+param2;returnresult;}JNIEXPORTvoidJNICALLJava_cn_taoweiji_nativemodule_NativeDemo_say(JNIEnv*env,jclass,jstringparam)(//std::string->jstringconstchar*param_char=env->GetStringUTFChars(param,NULL);std::stringstr=param_char;}JNIEXPORTjstringJNICALLJava_cn_taoweiji_nativemodule_NativeDemo_getInfo(JNIEnv*env,jclass)(//jstring->std::stringstd::stringstr="Hi,IamC++.";jstringresult=env->NewStringUTF(str.c_str());returnresult;}JNIEXPORTvoidJNICALLJava_cn_taoweiji_nativemodule_NativeDemo_nativeToJava(JNIEnv*env,jclass,jobjectobj)(//调用Java方法jclasscls=env->FindClass"cn/taoweiji/nativemodule/NativeDemo");//intsubtract(,intparam2)->(II)IjmethodIDmid=env->GetMethodID(cls,"subtract","(II)I");intresult=int)env->CallIntMethod(obj,mid,10,2);//std::cout<<result<<std::endl;//常见类型转换例子//StringgetInfo();//->()Ljava/lang/String;
//PackageinfogetPackageInfo(StringpackageName,intflags);//->(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;;第五步:编译生成JNI文件,按+B(Product->Build).编译后文件TjjjDEMO_MAC_JWIMTIDEMO_MAC_JNI防main.cpphcn_tacwEifi_natiuemoduIp_NativeDemo.hAEtiveDemo.cppAlOEMQ.MA.G_JNI▼IPrccFuetg——「ghowfnFinderOpenwithExternalEditorOpenAsShowFileInspectorNewFils...lOEMQ.MA.G_JNIAddFilesto“DEMOLMAC一JNiNewGroupNewGroupfromSeleciianSonbyNameSortbvTvp-e根据自己的电脑环境,查找编译后的文件,我的路径是/Users/Wiki/Library/Developer/Xcode/DerivedData/DEMO_MAC_JNI-clxymnzifegyfaajsaattzgxqfbr/Build/Products/Debug/DEMO_MAC_JNI第六步:编写JNI接口packagecn.taoweiji.nativemodule;/***包名和类名称一定要和前面的C++头文件对应
*cn_taoweiji_nativemodule_NativeDemo.h*/publicclassNativeDemo{publicstaticnativeintadd(intparaml,intparam2);publicstaticnativevoidsay(Stringname);publicstaticnativeStringgetInfo();publicstaticnativevoidnativeToJava(NativeDemonativeDemo);publicintsubtract(intparam1,intparam2){System.out.println"NativeDemo:"+String.format("%s-%s=%s,param1,param2,paraml-param2));returnparaml-param2;}}第七步:调用C++publicclassMain{static{System.loacT"/Users/Wiki/Library/Developer/Xcode/DerivedData/DEMO_MACJNI-clxymnzifegyfaajsaattzgxqfbr/Build/Products/Debug/DEMO_MAC_JNI");}publicstaticvoidmain(String[]args){Systemout.println("HelloWorld!");intresult=NativeDemo.add(1,2);Systemout.println("1+2="+String.valueOf(result));NativeDemo.say"Hello,IamJava.");Systemout.println("getInfo:"+NativeDemo.getInfo());NativeDemo.nativeToJavanewNativeDemo());3.在ANDROID项目中使用NDKAndroid的JNI开发,C++文件必须编写在独立的module里面,Java接口代码可以编写在app(module),也可以和C++放在同一个module,通过gradle关联。详细代码请自行下载demo浏览gradle配置(NativeModule)applyplugin:'com.android.library'android{compileSdkVersion23buildToolsVersion"24.0.0rc2"defaultConfig{minSdkVersio14targetSdkVersion23versionCodeL}…i0"buildTypes{release{minifyEnablefelseproguardFilesgetDefaultProguardFil'proguard-android.txt'),''ndk{moduleNa"joyrun"s"stlport_static"ldLi"log"//用于解决android_log_printabiFilte"armeabi","armeabi-v7a","x86","x86_64","arm64-v8a//add-fexceptionstoallowthrowerror//add-wto"formatnotastringliteralandnoformatarguments[-Werror=format-security"}—}compil—™编写JNI接口//NativeDemo.javapackagecn.taoweiji.nativemodule;publicclassNativeDemo{publicstaticnativeintadd(intparam1,intparam2);}编写C++接口代码,JNI文件目录默认是module/src/main/jni,可以通过gradle配置改变//cn_taoweiji_nativemodule_NativeDemo.h#include<jni.h>#ifndef_Included_cn_taoweiji_nativemodule_NativeDemo#define_Included_cn_taoweiji_nativemodule_NativeDemo#ifdefcplusplusextern"C"{#endif/*Class:cn_taoweiji_nativemodule_NativeDemoMethod:addSignature:(II)I*/JNIEXPORTjintJNICALLJava_cn_taoweiji_nativemodule_NativeDemo_add(JNIEnv*,jclass,jint,jint);#ifdefcplusplus}#endif#endif//NativeDemo.cpp#includencn_taoweiji_nativemodule_NativeDemo.hnJNIEXPORTjintJNICALLJava_cn_taoweiji_nativemodule_NativeDemo_add(JNIEnv*,jclass,jintparam1,jintparam2){jintresult=param1+param2;returnresult;}调用//静态加载static{}—”)//调用intresult=NativeDemo.add(1,2);Log.i("1+2=",String.valueOf(result));四、NDK开发要点编译文件分析将NativeModule编译后生成的aar文件后缀改成.zip解压,可以发现里面有个jni文件,打开可以看^U”armeabi”,“armeabi-v7a”,“x86”,“x86_64”,“arm64-v8a”等文件夹,再打开可以看到是以lib前缀的so格式文件,这就是编译后的native层文件,我们平常引用的第三方库(百度地图)也是要添加这些文件到我们的libs文件夹,不同的名称代表着不同平台相关的编译文件,市面上大多数的手机都是arm架构CPU,x86架构的手机几乎没人用(genymotion模拟器属于x86平台),所以我们通常发布APP不会考虑x86平台,仅仅添加armeabi文件即可,但是在开发过程中建议也添加x86的so文件,以方便我们在模拟器上运行。运行库Android平台带有一个微型的C运行库支持库,成为系统运行库。该运行库不支持一下特性:C标准库、异常支持、RTTI支持。NDK提供了用于补充系统运行库功能的一些额外的C++运行库。C++运行库C++异常支持C++RTTIC++标准库系统库NoNoNoGAbi++NoYesNoSTLportNoYesYesGNUSTLYesYesYesSTLportSTLport是一个开源的、多平台的C标准库实现。它提供一个C标准库头文件的完整集合以及对RTTI的支持。GNUSTLGNU标准C库,也叫libstdc-v3,是AndroidNDK最全面的标准C运行库。它是一个正在开发的、以实现ISO标准C库为目标的开源项目。gradle配置STL运行库引用“armeabi”,“armeabi-v7a”,“x86”,“x86_64”,“arm64-v8a”等平台配置C++输出logcat配置一个编译异常解决异常捕获//生成so文件的名称moduleName"joyrun"//引入STL标准库stl"stlport_static"//gnustl_static//用于解决android_log_printldLibs"log"abiFilters"armeabi","armeabi-v7a","x86","x86_64","arm64-v8a"//添加编译的平台//add-fexceptionstoallowthrowerror//add-wto"formatnotastringliteralandnoformatarguments[-Werror=format-security"IcFlags"-w-fexceptions"LOGCAT输出#include<android/log.h>#defineLOGI(...)__android_log_print(ANDROID_LOG_INFO,ntag_joyrun",VAARGS__)#defineLOGE(...)android_log_print(ANDROID_LOG_ERROR,"tag_joyrunn,VAARGS__)LOGE("HelloLogcat");类型转换//std::string->jstringstd::stringstr="HelloWorld";jstringresult=env->NewStringUTF(str.c_str());//jstring->std::stringjstringparam;constchar*param_char=env->GetStringUTFChars(param,NULL);std::stringstr=param_char;//jboolean两个值JNI_TRUE、JNI_FALSEC++调用JAVA代码//JavapublicstaticnativevoidnativeToJava(NativeDemonativeDemo);publicintsubtract(intparam1,intparam2){Log.e("NativeDemo",String.format("%s-%s=%s,param1,param2,param1-param2));returnparam1-param2;}//C++JNIEXPORTvoidJNICALLJava_cn_taoweiji_nativemodule_NativeDemo_nativeToJava(JNIEnv*env,jclass,jobjectobj){//调用Java方法jclasscls=env->FindClass"cn/taoweiji/nativemodule/NativeDemo");jmethodIDmid=env->GetMethodID(cls,"subtract","(II)I");intresult=int)env->CallIntMethod(obj,mid,10,2);//常见类型转换例子//StringgetInfo();//->()Ljava/lang/String;//PackageinfogetPackageInfo(StringpackageName,intflags);//->(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;;}一键生成从JAVA到C++接口代码脚本文件:autojavah.sh#!/bin/shexportProjectPath=$(cd"../$(dirname"$1")";pwd)exportTargetClassName="co.runner.app.jni.NativeDemo"exportSourceFile="${ProjectPath}/app/src/main/java"exportTargetPath="${ProjectPath}/jni-joyrun/src/main/jni"cd"${SourceFile}"javah-d${TargetPath}-classpath"${SourceFile}""${TargetClassName}echo-d${TargetPath}-classpath"${SourceFile}""${TargetClassName}"五、C++面向对象及标准库入门C++类定义//Demo.hpp#ifndefDemo_hpp#defineDemo_hpp#include<stdio.h>#include<string>classDemo{public:std::stringname;intage=0;voidsay();_5类方法的实现//Demo.cpp#include"Demo.hpp"#include<iostream>”idDemo:")='="~dl对象创建及访问对象的成员//对象创建Demod1;Demo*d2=newDemo;//运算符访问d1.say();//指针访问d2->say();//静态函数访问intresult=Demo::add(1,2);std::cout<<"1+2=<<result<<std::endl;LIST链表//include相关文件#include<stdio.h>#include<iostream>#include<list>#include"Demo.hpp
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《微专题小练习》英语 详解答案
- 2024年供应链行业的创新案例分析试题及答案
- 2025年永磁无刷直流电动机项目发展计划
- 2025年全自动变焦照相机合作协议书
- 数字化时代的仓储技术挑战试题及答案
- CPSM考试趋势与试题及答案
- 广西桂林十八中2025年高考冲刺化学模拟试题含解析
- 树木生长的生理基础与影响因素试题及答案
- 2025届江苏省苏、锡、常、镇高三(最后冲刺)化学试卷含解析
- 考生必看CPMM试题及答案
- 平北黄岩油气田群调整井项目(第一批)环评报告
- 过程审核检查表-示例
- 二年级上册音乐课程纲要
- 《口腔医学课件:正畸治疗方案设计与矫治技术分析》
- 专职安全管理机构设置文件范本
- 谈判:如何在博弈中获得更多
- 复方氨基酸注射液的汇总
- 门窗设计师职位描述与岗位职责
- SYB创业培训游戏模块2课件
- 美国密码法律制度概览 2023
- 股骨粗隆间骨折合并下肢静脉血栓的护理查房
评论
0/150
提交评论