Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
C++ based mobile application
Search
Michał Kowalczyk
November 15, 2017
Programming
41
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
C++ based mobile application
Slides for a talk given during code::dive 2017.
Michał Kowalczyk
November 15, 2017
More Decks by Michał Kowalczyk
See All by Michał Kowalczyk
Test maintainability
mkk
0
51
Other Decks in Programming
See All in Programming
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
390
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
180
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
6.6k
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
280
Workers Cache を知る
syumai
0
360
残高管理から台帳サービスへの進化
artoy
1
200
気持ちぃ〜角丸 Squircle
ryu1013
0
310
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
150
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
2
560
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
160
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
140
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
28
32k
Featured
See All Featured
The agentic SEO stack - context over prompts
schlessera
0
970
How to Ace a Technical Interview
jacobian
280
24k
First, design no harm
axbom
PRO
2
1.3k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Building AI with AI
inesmontani
PRO
1
1.3k
Technical Leadership for Architectural Decision Making
baasie
3
600
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
エンジニアに許された特別な時間の終わり
watany
109
250k
Test your architecture with Archunit
thirion
2
2.4k
WENDY [Excerpt]
tessaabrams
14
40k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Transcript
C++ based mobile application Michał Kowalczyk
A story a.k.a. the agenda
Mobile app Mobile device Android / iOS Android Wear /
watchOS Android TV / tvOS Android Auto…
Android Linux based Java / Kotlin C / C++ Bionic
ARM / MIPS / x86 / x86-64
iOS FreeBSD based Objective-C / Swift C / C++ Only
Apple devices ARM / x86-64
Visual Screen size Screen density Layout
Why C++ 75% of top 50 Android apps use it
Portability Reducing code duplicity Extra libraries (TensorFlow Mobile) Performance Reducing battery usage Obfuscation
Why not C++ Complex technological stack Cost of JNI calls
Not whole API available Increasing Android apk size
Alternatives Xamarin NativeScript / React Native Kotlin Native
Boundaries of C++ No boundary Platform specific vs platform agnostic
Bridging code
Bridging code Data types Exceptions Memory management Java Native Interface
Objective-C++
Bridging code - handwritten Small projects Specialised needs Our project
in TomTom Nearly 35 000 lines of C++ Nearly 10 000 lines of Java
Bridging code generation - SWIG Mature Many languages supported (excluding
Objective-C) C / C++ centric
SWIG input - C++ 1 #include <string> 2 3 class
BusinessLogic 4 { 5 public: 6 std::string helloWorld(); 7 }; 8 9 std::string BusinessLogic::helloWorld() 10 { 11 return "Hello world!"; 12 }
SWIG input - interface definition 1 #ifdef SWIG 2 %module
business_logic 3 %include "std_string.i" 4 %{ 5 #include "BusinessLogic.hpp" 6 %} 7 #endif 8 9 %include "BusinessLogic.hpp"
SWIG output - C++ 1 SWIGEXPORT jstring JNICALL Java_business_1logicJNI_BusinessLogic_1helloWorld(JNIEnv *jenv,
2 jclass jcls, 3 jlong jarg1, 4 jobject jarg1_) { 5 jstring jresult = 0 ; 6 BusinessLogic *arg1 = (BusinessLogic *) 0 ; 7 std::string result; 8 9 (void)jenv; 10 (void)jcls; 11 (void)jarg1_; 12 arg1 = *(BusinessLogic **)&jarg1; 13 result = (arg1)->helloWorld(); 14 jresult = jenv->NewStringUTF((&result)->c_str()); 15 return jresult; 16 }
SWIG output - Java 1 public class BusinessLogic { 2
// ... 3 4 protected void finalize() { 5 delete(); 6 } 7 8 public synchronized void delete() { 9 if (swigCPtr != 0) { 10 if (swigCMemOwn) { 11 swigCMemOwn = false; 12 business_logicJNI.delete_BusinessLogic(swigCPtr); 13 } 14 swigCPtr = 0; 15 } 16 } 17 18 public String helloWorld() { 19 return business_logicJNI.BusinessLogic_helloWorld(swigCPtr, this); 20 } 21 }
Use SWIG generated bridging code 1 public class JavaApp {
2 public static void main(String argv[]) { 3 System.loadLibrary("business_logic"); 4 final BusinessLogic logic = new BusinessLogic(); 5 System.out.println(logic.helloWorld()); 6 } 7 }
Bridging code generation - Djinni 3 years old Java /
Objective-C / Python IDL centric
Djinni input - interface definition 1 BusinessLogic = interface +c
{ 2 static create(): BusinessLogic; 3 helloWorld(): string; 4 }
Djinni output - C++ 1 #include <memory> 2 #include <string>
3 4 class BusinessLogic { 5 public: 6 virtual ~BusinessLogic() {} 7 8 static std::shared_ptr<BusinessLogic> create(); 9 10 virtual std::string helloWorld() = 0; 11 };
SWIG vs Djinni Green field Easy vs customisable Swift support
Namespaces / packages / exceptions
Android gradle Android NDK (toolchains / debugger / API) Android
SDK (adb, avd)
None
None
Android version API version Reached users Release date 2.3.3-2.3.7 10
100,0% 2010 4.0.3-4.0.4 15 99,4% 2011 4.1.x 16 98,8% 2012 4.2.x 17 96,5% 2012 4.3 18 93,2% 2012 4.4 19 92,2% 2013 5.0 21 77,7% 2014 5.1 22 71,0% 2014 6.0 23 50,0% 2015 7.0 24 18,0% 2016 7.1 25 2,2% 2016 8.0 26 0,2% 2017
None
None
None
None
Android manifest file 1 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 2 package="pl.ekk.mkk.androidproject"> 3 <application
4 android:allowBackup="true" 5 android:icon="@mipmap/ic_launcher" 6 android:label="@string/app_name" 7 android:roundIcon="@mipmap/ic_launcher_round" 8 android:supportsRtl="true" 9 android:theme="@style/AppTheme"> 10 <activity android:name=".MainActivity"> 11 <intent-filter> 12 <action android:name="android.intent.action.MAIN"/> 13 <category android:name="android.intent.category.LAUNCHER"/> 14 </intent-filter> 15 </activity> 16 </application> 17 </manifest>
Activity 1 public class MainActivity extends AppCompatActivity { 2 static
{ 3 System.loadLibrary("native-lib"); 4 } 5 6 @Override 7 protected void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.activity_main); 10 11 TextView tv = (TextView) findViewById(R.id.sample_text); 12 tv.setText(stringFromJNI()); 13 } 14 15 public native String stringFromJNI(); 16 }
Native code 1 #include <jni.h> 2 #include <string> 3 4
extern "C" 5 JNIEXPORT jstring 6 7 JNICALL 8 Java_pl_ekk_mkk_androidproject_MainActivity_stringFromJNI( 9 JNIEnv *env, 10 jobject /* this */) 11 { 12 std::string hello = "Hello from C++"; 13 return env->NewStringUTF(hello.c_str()); 14 }
CMake 1 add_library( native-lib 2 SHARED 3 src/main/cpp/native-lib.cpp ) 4
5 find_library( log-lib 6 log ) 7 8 target_link_libraries( native-lib 9 ${log-lib} )
None
www.imobie.com/faq/android-faqs.htm
iOS Must own Mac Developer ID Provisioning profile Xcode project
from CMake
iOS minimum version
iOS version Reached users Release date Earlier 100% < 2016
iOS 10 90% 2016 iOS 11 52% 2017
None
None
ViewController.h 1 #import <UIKit/UIKit.h> 2 3 @interface ViewController : UIViewController
4 5 @property (weak, nonatomic) IBOutlet UILabel *label; 6 7 @end
ViewController.m 1 #import "ViewController.h" 2 #import "ObjCppWrapper.h" 3 4 @interface
ViewController () 5 6 @end 7 8 @implementation ViewController 9 10 - (void)viewDidLoad { 11 [super viewDidLoad]; 12 13 ObjCppWrapper* wrapper = [[ObjCppWrapper alloc] init]; 14 _label.text = [wrapper stringFromCpp]; 15 } 16 17 @end
ObjCppWrapper.h 1 @interface ObjCppWrapper : NSObject 2 3 - (nonnull
NSString *)stringFromCpp; 4 5 @end
ObjCppWrapper.mm 1 #import <Foundation/Foundation.h> 2 #import "ObjCppWrapper.h" 3 #include "NativeLib.hpp"
4 5 @implementation ObjCppWrapper { 6 } 7 8 - (nonnull NSString *)stringFromCpp { 9 NativeLib lib; 10 const std::string string = lib.stringFromCpp(); 11 return [[NSString alloc] initWithBytes:string.data() 12 length:static_cast<NSUInteger>(string.size()) 13 encoding:NSUTF8StringEncoding]; 14 } 15 16 @end
NativeLib 1 #include <string> 2 3 class NativeLib 4 {
5 public: 6 std::string stringFromCpp(); 7 }; 8 9 std::string NativeLib::stringFromCpp() 10 { 11 return "Hello from C++"; 12 }
None
Advice Find Android / iOS developers Consult C++ boundaries /
use djinni Understand what you copy-paste from stackoverflow CrystaxNDK Don’t handwrite bridging code Limit ABIs while development; use ccache Use platform specific tools for platform agnostic code Use logging
Links developer.android.com/training developer.android.com/ndk www.crystax.net developer.apple.com/documentation www.swig.org github.com/dropbox/djinni github.com/michal-kowalczyk/pushuppal github.com/michal-kowalczyk/trambambule-helper youtu.be/eNppYcmsx-g
@michal_k_k www.mkk.ekk.pl Questions?