All Projects → ademar111190 → Cppandroidiosexample

ademar111190 / Cppandroidiosexample

An application example using the same C++ code on both an Android project and an iPhone project.

Programming Languages

java
68154 projects - #9 most used programming language
c
50402 projects - #5 most used programming language
swift
15916 projects
kotlin
9241 projects
cpp
1120 projects

Projects that are alternatives of or similar to Cppandroidiosexample

Play Scala Slick Example
Example Play Scala project with Slick
Stars: ✭ 59 (-69.11%)
Mutual labels:  example, example-project
Ueberauth example
Example Phoenix application using Überauth for authentication
Stars: ✭ 180 (-5.76%)
Mutual labels:  example, example-project
Play Java Websocket Example
Example Play Java application showing Websocket usage with Akka actors
Stars: ✭ 86 (-54.97%)
Mutual labels:  example, example-project
Open Source Ios Apps
📱 Collaborative List of Open-Source iOS Apps
Stars: ✭ 28,826 (+14992.15%)
Mutual labels:  iphone, example
Godot tutorials
Code and examples for KidsCanCode Godot Tutorials.
Stars: ✭ 119 (-37.7%)
Mutual labels:  example, example-project
Adhokku
A toy PaaS
Stars: ✭ 32 (-83.25%)
Mutual labels:  example, example-project
Go Examples
examples written using golang third party packages.
Stars: ✭ 106 (-44.5%)
Mutual labels:  example, example-project
play-scala-secure-session-example
An example Play application showing encrypted session management
Stars: ✭ 54 (-71.73%)
Mutual labels:  example, example-project
Razzle Material Ui Styled Example
Razzle Material-UI example with Styled Components using Express with compression
Stars: ✭ 117 (-38.74%)
Mutual labels:  example, example-project
Annotation Processing Example
It is the example project for the annotation processing tutorial.
Stars: ✭ 116 (-39.27%)
Mutual labels:  example, example-project
Play Samples
Stars: ✭ 335 (+75.39%)
Mutual labels:  example, example-project
Play Scala Isolated Slick Example
Example Play Slick Project
Stars: ✭ 155 (-18.85%)
Mutual labels:  example, example-project
Create React App Typescript Todo Example 2020
🚀 Create React App TypeScript Todo Example 2020
Stars: ✭ 255 (+33.51%)
Mutual labels:  example, example-project
Owin Webapi Service
✅ OWIN / WebAPI windows service example. Includes attribute based routing sample
Stars: ✭ 175 (-8.38%)
Mutual labels:  example, example-project
lagom-samples
developer.lightbend.com/start/?group=lagom
Stars: ✭ 85 (-55.5%)
Mutual labels:  example, example-project
Jni By Examples
🎇Fun Java JNI By Examples - with CMake and C++ (or C, of course!) ‼️ Accepting PRs
Stars: ✭ 99 (-48.17%)
Mutual labels:  example, example-project
play-java-ebean-example
Example Play application showing Java with Ebean
Stars: ✭ 54 (-71.73%)
Mutual labels:  example, example-project
play-scala-anorm-example
Example Play Database Application using Anorm
Stars: ✭ 41 (-78.53%)
Mutual labels:  example, example-project
Godot public examples
Stars: ✭ 106 (-44.5%)
Mutual labels:  example, example-project
Android Clean Architecture Mvvm Dagger Rx
Implemented by Clean Architecture, Dagger2, MVVM, LiveData, RX, Retrofit2, Room, Anko
Stars: ✭ 138 (-27.75%)
Mutual labels:  example, example-project

C++ Android Ios Example

An application example using the same C++ code on both an Android project and an iPhone project.

ScreenShot

You can clone the repo and run the iPhone project as well as the Android project. Following I'll explain step by step what I did, but first let take a look at this diagram.

Arch

Each OS has its UI and peculiarities, so we intend to write specific code to each platform in this regard. In other hands, all logic code, business rules, and things that can be shared we intend to write using C++, so we can compile the same code to each platform.

In the diagram, you can see the C++ layer at the lowest level. All shared code is in this segment. The highest level is regular Obj-C / Java / Kotlin code, no news here, the hard part is the middle layer.

The middle layer to iOS side is simple; you only need to configure your project to build using a variant of Obj-c know as Objective-C++ and it is all, you have access to C++ code.

The thing became harder on the Android side, both languages, Java and Kotlin, on Android, run under a Java Virtual Machine. So the only way to access C++ code is using JNI, please take time to read the basics of JNI. Fortunately, today's Android Studio IDE has vast improvements on JNI side, and a lot of problems are shown to you while you edit your code.

The code by steps

Our sample is a simple app that you send a text to CPP, and it converts that text to something else and returns it. The idea is, iOS will send "Obj-C" and Android will send "Java" from their respective languages, and the CPP code will create a text as a follow "cpp says hello to << text received >>".

Shared CPP code

First of all, we are going to create the shared CPP code, doing it we have a simple header file with the method declaration concatenateMyStringWithCppString that receives the desired text, and the CPP implementation file.

Unix

An interesting bonus is, we can also use the same code for Linux and Mac as well as other Unix systems. This possibility is especially useful because we can test our shared code faster, so we are going to create the Main.cpp File to execute it from our machine and see if the shared code is working. To build the code, you need to execute shell helper file, and finally, you can run it with a simple ./main the result should be:

$ sh compileToUnix.sh 
Compiled, now execute using ./main
$ ./main 
cpp says hello to Unix

iOS

It is time to implement on the mobile side. As far as iOS has a simple integration we are starting with it. Our iOS app is a typical Obj-c app with only one difference; the files are .mm and not .m. i.e. It is an Obj-C++ app, not an Obj-C app.

To a better organization, we create the CoreWrapper file; it has the responsibility to convert CPP types and calls to Obj-C types and calls. It is not mandatory once you can call CPP code on any file you want, but it helps to keep the organization, and outside your wrapper files you maintain a complete Obj-C styled code, only the wrappers file become CPP styled.

Once your wrapper is connected to the CPP code, you can use it as a standard Obj-C code, on our example, our ViewController is calling the wrapper and taking the string to populate our storyboard layout.

Take a look of how the app looks:

Xcode iPhone

Android

Now it is time for Android integration. Android uses Gradle as the build system, and to C/C++ code it uses CMake. So the first thing we need to do is to configure the CMake on gradle file and the second step is to add the CMakeList file. The CMake file is where you need to add the CPP files and header folders you will use on the project, on our example, we are adding the CPP folder and the Core.h/.cpp files. Note the proguard is turned ON, it is only to show the integration works with proguard as well without it. To know more about C/C++ configuration please read it.

Now the core code is part of our app it is time to create the bridge, to make the things more simple and organized we create a specific class named CoreWrapper to be our wrapper between JVM and CPP. Note this class has a native method and loads a native library named native-lib. This library is the one we create, in the end, the CPP code will become a shared object .so File embed in our APK, and the loadLibrary will load it. Finally, when you call the native method, the JVM will delegate the call to the loaded library.

Now the most strange part of Android integration is the JNI; please look at native-lib.cpp file, the first thing you will notice is the extern "C" this part is necessary to JNI work correctly with our CPP code and method linkages. You will also see some symbols JNI uses to works with JVM as JNIEXPORT and JNICALL. To you understand the meaning of those things, it is necessary to take a time and read it, for this tutorial purposes just consider these things as boilerplate.

One significant thing and usually the root of a lot of problems is the name of the method; it needs to follow the pattern "Java_package_class_method". Currently, Android studio has excellent support for it so it can generate this boilerplate automatically and show to you when it is correct or not named. On our example our method is named "Java_ademar_androidioscppexample_CoreWrapper_concatenateMyStringWithCppString" it is because "ademar.androidioscppexample" is our package, so we replace the "." by "_", CoreWrapper is the class where we are linking the native method and "concatenateMyStringWithCppString" is the method name itself.

As we have the method correctly declared it is time to analyze the arguments, the first parameter is a pointer of JNIEnv it is the way we have access to JNI stuff, it is crucial to we make our conversions as you will see soon. The second is a jobject it is the instance of the object you had used to call this method. You can think it as the java "this", on our example we do not need to use it, but we still need to declare it. After this jobject we are going to receive the arguments of the method because our method has only one argument, a String "myString" we have only a "jstring" with the same name. Notice also our return type is also a jstring, it is because our Java method returns a String, for more information about Java/JNI types please read it.

The final step is to convert the JNI types to the types we use on CPP side. On our example, we are transforming the jstring to a const char * sending it converted to the CPP, getting the result and converting back to jstring. As all other steps on JNI, it is not hard; it is only boilerplated, all the work is done by the JNIEnv* argument we receive when we call the GetStringUTFChars and NewStringUTF. After it our code is ready to run on Android devices, lets take a look.

AndroidStudio Android

Bonus Swift and MacOS

Currently, there is no integration between swift and C++, so to use our C++ shared code on Swift it is necessary to use Objective-C++ as a bridge. The code is almost the same as the iOS sample, the only additional stuff is related to Swift - Obj-C integration, it is the Bridge header. To see how flexible our CPP code is, the swift sample is a MacOS app, enjoy.

Xcode-Swift Swift

Thank you for read, please let me know any question you have.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].