CC++在JavaAndroid和ObjectiveC三大平台下实现混合编程.docx_第1页
CC++在JavaAndroid和ObjectiveC三大平台下实现混合编程.docx_第2页
CC++在JavaAndroid和ObjectiveC三大平台下实现混合编程.docx_第3页
CC++在JavaAndroid和ObjectiveC三大平台下实现混合编程.docx_第4页
CC++在JavaAndroid和ObjectiveC三大平台下实现混合编程.docx_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Android和iOS开发都支持C+开发,可以一套代码多平台使用。同时C+难以反编译的特性也可以为Android开发带来代码的保密,另一native特性也可以提高代码的运行效率。一、为什么使用C/C+1. 便于移植,用C/C+写得库可以方便在其他的平台上再次使用。2. 代码的保护,由于java层代码很容易被反编译,而C/C+库反汇难度较大。3. 提高程序的执行效率,将要求高性能的应用逻辑使用C/C+开发,从而提高应用程序的执行效率。4. 访问现有开源库,需要访问底层的API或引用一些只有C/C+的库。二、开发工具介绍尽管Android Studio可以同时编写C+和Java代码,写完就可以编译运行,但是对联想和错误提示并不是非常友好,个人建议C+的整体代码使用Visual Studio或Xcode编译开发,联想功能非常友好,编译速度很快,调试也非常方便。 Visual Studio(PC) Xcode(Mac) Android Studio(多平台) eclipse(多平台)三、第一行代码1. 如何在Objective-C项目中使用C+;在Objective-C使用C/C+非常简单,仅仅需要把.m后缀的文件改成.mm即可使用C+,我们通常不会把.mm的文件写到整个项目都有,而是设计一个接口,用来做两个语言之间的桥梁,他们之间的交互仅仅在这个接口。要点:String类型转换/ Objective-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;NSLog(%,ocString2);记得要include相关的文件#include #include 2.在普通的JAVA项目中使用JNI编程由于我是在MAC下办公,所以这里就介绍如何在MAC下进行JNI开发,在Windows平台下的Virtual Studio也很简单。第一步:在Xcode下创建一个普通的C+项目第二步:关联JavaVM的Framework路径:/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaNativeFoundation.framework/第三步:创建头文件,用于和Java交互 cn_taoweiji_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 Java_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#endif第四步:创建实现 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_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+.; jstring result = env-NewStringUTF(str.c_str(); return result;JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_nativeToJava(JNIEnv * env, jclass, jobject obj) / 调用Java方法 jclass cls = env-FindClass(cn/taoweiji/nativemodule/NativeDemo); /int subtract(int , int param2) - (II)I jmethodID 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).编译后文件根据自己的电脑环境,查找编译后的文件,我的路径是/Users/Wiki/Library/Developer/Xcode/DerivedData/DEMO_MAC_JNI-clxymnzifegyfaajsaattzgxqfbr/Build/Products/Debug/DEMO_MAC_JNI第六步:编写JNI接口package cn.taoweiji.nativemodule;/* * 包名和类名称一定要和前面的C+头文件对应 * cn_taoweiji_nativemodule_NativeDemo.h */public class NativeDemo public static native 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, param1 - param2); return param1 - param2; 第七步:调用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 = NativeDemo.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开发,C+文件必须编写在独立的module里面,Java接口代码可以编写在app(module),也可以和C+放在同一个module,通过gradle关联。详细代码请自行下载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-android.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 -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#include #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 *, 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;调用/ 静态加载static System.loadLibrary(joyrun);/调用int result = NativeDemo.add(1,2);Log.i(1+2=,String.valueOf(result);四、NDK开发要点编译文件分析将NativeModule编译后生成的aar文件后缀改成.zip解压,可以发现里面有个jni文件,打开可以看到”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+NoYesNoSTLportNoYesYesGNU STLYesYesYes1. STLportSTLport是一个开源的、多平台的C标准库实现。它提供一个C标准库头文件的完整集合以及对RTTI的支持。2. GNU STLGNU标准C库,也叫libstdc-v3,是Android NDK最全面的标准C运行库。它是一个正在开发的、以实现ISO标准C库为目标的开源项目。gradle配置1. STL运行库引用2. “armeabi”, “armeabi-v7a”, “x86”, “x86_64”, “arm64-v8a”等平台配置3. C+输出logcat配置4. 一个编译异常解决5. 异常捕获6. / 生成so文件的名称7. moduleName joyrun8. / 引入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 -fexceptionsLOGCAT输出#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);类型转换/ std:string - jstringstd:string str = Hello World;jstring result = env-NewStringUTF(str.c_str();/ jstring - std:stringjstring param;const char *param_char = env-GetStringUTFChars(param, NULL);std:string str = param_char;/ jboolean 两个值 JNI_TRUE、JNI_FALSEC+调用JAVA代码/Javapublic static native void nativeToJava(NativeDemo nativeDemo);public int subtract(int param1, int param2) Log.e(NativeDemo, String.format(%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) / 调用Java方法 jclass cls = env-FindClass(cn/taoweiji/nativemodule/NativeDemo); jmethodID mid = env-GetMethodID(cls, subtract, (II)I); int result = (int) env-CallIntMethod(obj, mid, 10, 2); /常见类型转换例子 /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 ProjectPath=$(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 $SourceFile $TargetClassName五、C+面向对象及标准库入门C+类定义/ 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 */类方法的实现/ Demo.cpp#include Demo.hpp#include void Demo:say() std:coutname = name,age = agesay();/静态函数访问int result = Demo:add(1,2);std:cout1 + 2 = resultstd:endl;LIST链表/include相关文件#include #include #include #include Demo.hp

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论