如何为Android和iOS使用相同的C ++代码?
Android与NDK支持C / C ++代码, Objective-C ++也支持iOS,那么如何用Android和iOS共享的本机C / C ++代码编写应用程序?
这里是我要做的一个图表:
所以按照下面的步骤走吧:
-
创build一个core.h文件,在这里我们定义在Android和iOS上运行的方法
concateneMyStringWithCppString
。 此方法将从Android或iOS应用程序接收string,并将其与一个公共string连接,并返回此连接的string。#ifndef __HelloCpp__Core__ #define __HelloCpp__Core__ #include <iostream> const char* concateneMyStringWithCppString(const char* myString); #endif /* defined(__HelloCpp__Core__) */
-
现在使用方法实现的core.cpp文件,我们有一个string
CPP_BASE_STRING
,并将它与参数const char* myString
连接起来,并返回它。myString
将由Android或iOS交付。#include "Core.h" const char* CPP_BASE_STRING = "cpp says hello world to %s"; const char* concateneMyStringWithCppString(const char* myString) { char* concatenedString = new char[strlen(CPP_BASE_STRING) + strlen(myString)]; sprintf(concatenedString, CPP_BASE_STRING, myString); return concatenedString; }
-
所以我们需要一个包装到iOS和另一个到Android。 首先,我们将创buildiOS包装。 编写包装器标题CoreWrapper.h:
#import <Foundation/Foundation.h> #import "Core.h" @interface CoreWrapper : NSObject + (NSString*) concateneMyStringWithCppString:(NSString*)myString; @end
-
现在封装代码,它需要一个Objective-C ++代码,所以CoreWrapper.mm文件。
#import "CoreWrapper.h" @implementation CoreWrapper + (NSString*) concateneMyStringWithCppString:(NSString*)myString { return [NSString stringWithUTF8String:concateneMyStringWithCppString([myString UTF8String])]; } @end
-
在普通的视图控制器上使用核心包装器,首先是View Controller头,这样ViewController.h
#import <UIKit/UIKit.h> #import "CoreWrapper.h" @interface ViewController : UIViewController @end
-
现在,ViewController.mm文件:
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // A normal UITextView UITextView* txtHelloCpp = [[UITextView alloc] initWithFrame:CGRectMake(0, 140, 320, 20)]; // Here we set the text with shared cpp code. [txtHelloCpp setText:[CoreWrapper concateneMyStringWithCppString:@"Objective-c"]]; // Normal things again [self.view addSubview:txtHelloCpp]; [txtHelloCpp release]; } @end
-
所以这是所有的iOS,现在的Android应用程序。 要在Android中执行此操作,您需要使用Android NDK ,CPP中的Android包装程序以及应用程序和Android生成文件。
-
首先Android.mk,你需要链接共享的CPP代码“core.cpp”与CPP Android包装,所以在我的例子中,我做了我的Android.mk文件,如下所示。
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := HelloCpp LOCAL_SRC_FILES := CoreWrapper.cpp LOCAL_SRC_FILES += ../../CPP/Core.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)../../CPP/ include $(BUILD_SHARED_LIBRARY)
-
这是我的示例应用程序的文件夹结构。 我没有显示iOS应用程序结构,因为XCode为我们pipe理:
/- |-Android- |-jni - |-Android.mk |-Application.mk |-CoreWrapper.cpp |-other android folders like res and src |-CPP----- |-Core.h |-Core.cpp
-
现在Application.mk:
APP_STL := gnustl_static APP_ABI := all
-
这里是使用
JNI
与CPP代码进行交互的CoreWrapper.cpp。#include <string.h> #include <jni.h> #include "../../CPP/Core.h" extern "C" { JNIEXPORT jstring JNICALL Java_la_jurema_doses_hellocpp_MainActivity_concateneMyStringWithCppString(JNIEnv* env, jobject thiz, jstring myString) { return env->NewStringUTF(concateneMyStringWithCppString(env->GetStringUTFChars(myString, 0))); } }
-
现在在Java中实现,使用正常的
Activity
,文件MainActivity.java:public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // A normal textview TextView textView = new TextView(getApplicationContext()); // set the text of textview with the string of shared cpp code textView.setText(concateneMyStringWithCppString("Javaaaa")); // normal things setContentView(textView); // only interface things nothng important textView.setTextSize(50); textView.setTextColor(Color.BLACK); textView.setGravity(Gravity.CENTER); } // very important private native String concateneMyStringWithCppString(String myString); static { System.loadLibrary("HelloCpp"); } }
就是这样,如果你做得对,你得到这样的东西:
你可以在这里得到Github的完整例子,如果你了解葡萄牙语,你可以在这里看到我在Google Docs上的介绍。