-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfeed.xml
More file actions
2350 lines (1839 loc) · 462 KB
/
feed.xml
File metadata and controls
2350 lines (1839 loc) · 462 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Pixio - Mobile Technology Consulting Services</title>
<description>Pixio is a team of educators and developers specializing in native mobile development and hardware communication. We have gained a reputation as one of the top mobile technology consulting services.</description>
<link>http://www.pixio.com/</link>
<atom:link href="http://www.pixio.com/feed.xml" rel="self" type="application/rss+xml" />
<pubDate>Tue, 25 Oct 2016 12:50:45 -0600</pubDate>
<lastBuildDate>Tue, 25 Oct 2016 12:50:45 -0600</lastBuildDate>
<generator>Jekyll v3.3.0</generator>
<item>
<title>Battle of the bOStards: Activities vs. View Controllers</title>
<description><p>Like most things in life, there is almost always a Game of Thrones (GoT) analogy that can be used to describe it perfectly. In the case of Android vs. iOS there is no better analogy in the GoT universe than the 2016 episode <a href="http://www.imdb.com/title/tt4283088/?ref_=fn_al_tt_1">Battle of the Bastards</a>. For those that do not know what GoT is, or have yet to see the episode, I will give you a brief spoiler-proof overview. The plot line is pretty straightforward, there is a battle between good and evil. Now most you are probably asking yourself, how in the world does a battle between good and evil from a fantasy TV show relate to Android vs. iOS? Pretty much every mobile developer I have ever come across has a predetermined opinion on which mobile platform is better, and in most developer’s eyes, usually one of the platforms is good and the other is pure evil. (Oh, and FYI, if they say that they prefer Windows Phone, run and hide, because only a white walker would support the platform of the living dead).</p>
<p>The focus of today is Android Activities vs. iOS View Controllers. In this article I will describe what each of these things are, their pros and cons, and provide a small example for each highlighting a few of their features. Let’s first start with Activities.</p>
<h4 id="activities">Activities:</h4>
<p>An <a href="https://developer.android.com/guide/components/activities.html">Activity</a> is a single, focused thing that a user can do. This definition might seem very vague and general - that’s because Activities are meant to be general purpose. But while Activities might be able to perform a number of different actions, one thing remains the same: Activities are a crucial part of every Android application. In fact they are so crucial that every single android application is required to have at least one Activity, and oftentimes they are made up of a number of them, unless of course a developer chooses to use fragments, but that is an entirely different subject for another day.
An Activity often acts as the Controller in the Model-View-Controller (MVC) architecture. It is responsible for communicating with the model and determining what information to display to the user. Beyond their immediate function, they have a complex “life cycle”: the ways in which they are created, displayed, hidden, and destroyed by the system. This life cycle consists of a number of different methods that are called at different points during the Activities life. Some of these methods include <code>onCreate()</code>, <code>onResume()</code>, <code>onStop()</code> and <code>onDestroy()</code> just to name a few. It is crucial for any Android developer to not only know of all these life cycle methods, but to also understand when and why they are called during the activities life cycle. </p>
<p>Now that you have had an overview on what an activity is, and a few of its life cycle methods, let’s jump right into an example. In this example we will create a simple activity and demonstrate when a few of its life cycle methods are called.
First let’s start a new Android studio project. You can name your project whatever you like, I chose ActivityExample. Next let’s select the minimum SDk as API 16, start with a blank activity, and leave the activity name as MainActivity. Now that we are all set up let’s see what we have got to work with. If you open the <code>MainActivity.java</code> file you will see that we have one method in our class, <code>onCreate()</code>. <code>onCreate()</code> is crucial to every activity because it specifies what needs to happen when an Activity is created for the first time (think of it as a constructor). By default the MainActivity is making a call to super and setting a view that will be displayed to the user. This is very typical of an Activity, and most Activities will make at a minimum these two calls in <code>onCreate()</code>.</p>
<p>Now run the app. You should see a blank screen with the famous, “Hello World” displayed on it. Now that you have a basic activity up and running, let’s do something useful with it. In Android Studio navigate to the <code>activity_main.xml</code>layout file in the res/layout folder and open it up. Change the layout to a <code>RelativeLayout</code> and put an <code>EditText</code> object in the center of the screen, making sure to change the background color so we can see it. Like so.</p>
<div class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
<span class="nt">&lt;RelativeLayout</span>
<span class="na">android:id=</span><span class="s">"@+id/activity_main"</span>
<span class="na">xmlns:android=</span><span class="s">"http://schemas.android.com/apk/res/android"</span>
<span class="na">xmlns:app=</span><span class="s">"http://schemas.android.com/apk/res-auto"</span>
<span class="na">xmlns:tools=</span><span class="s">"http://schemas.android.com/tools"</span>
<span class="na">android:layout_width=</span><span class="s">"match_parent"</span>
<span class="na">android:layout_height=</span><span class="s">"match_parent"</span>
<span class="na">tools:context=</span><span class="s">"org.com.activityexample.MainActivity"</span>
<span class="na">android:gravity=</span><span class="s">"center"</span>
<span class="na">android:background=</span><span class="s">"@android:color/black"</span><span class="nt">&gt;</span>
<span class="nt">&lt;EditText</span>
<span class="na">android:id=</span><span class="s">"@+id/textbox"</span>
<span class="na">android:layout_width=</span><span class="s">"300dp"</span>
<span class="na">android:layout_height=</span><span class="s">"50dp"</span>
<span class="na">android:background=</span><span class="s">"@android:color/white"</span>
<span class="nt">/&gt;</span>
<span class="nt">&lt;/RelativeLayout&gt;</span>
</code></pre></div>
<p>Now that we have something useful on screen, let’s run the application again and test it out. Click on the text box and enter in some text. It appears to be working right? Not so fast, let’s see what happens to our text when we rotate the device. Test it out… Poof, your text vanished like Rob Stark during the Red Wedding. So what happened? What evil force stole your text? Any guesses? And no it wasn’t the blood magic of the Red Woman. Instead, your text is no longer alive (in memory) because the Activity that it lived in is no longer alive. But how can the Activity no longer be alive? I can see it on screen with my own two eyes. The reason my friends, is because of the Activity’s life cycle. Every time an Activity is rotated it is destroyed and created again. So any data that was living in the previous activity is destroyed when a call to <code>onDestroy()</code> is made by the application. Still don’t believe me? Test it out. Override the <code>onDestroy()</code> method and add a log message to the debug log, and while we are at it let’s also add a log message to the <code>onCreate()</code> method. Like so.</p>
<div class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onCreate</span><span class="o">(</span><span class="n">Bundle</span> <span class="n">savedInstanceState</span><span class="o">)</span>
<span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onCreate</span><span class="o">(</span><span class="n">savedInstanceState</span><span class="o">);</span>
<span class="n">setContentView</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">layout</span><span class="o">.</span><span class="na">activity_main</span><span class="o">);</span>
<span class="n">String</span> <span class="n">message</span> <span class="o">=</span> <span class="s">"What is dead may never die."</span><span class="o">;</span>
<span class="n">Log</span><span class="o">.</span><span class="na">d</span><span class="o">(</span><span class="s">"Debug: "</span><span class="o">,</span> <span class="n">message</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onDestroy</span><span class="o">()</span>
<span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onDestroy</span><span class="o">();</span>
<span class="n">String</span> <span class="n">message</span> <span class="o">=</span> <span class="s">"To be called or not to be called, that is the question."</span><span class="o">;</span>
<span class="n">Log</span><span class="o">.</span><span class="na">d</span><span class="o">(</span><span class="s">"Debug: "</span><span class="o">,</span> <span class="n">message</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div>
<p>Run the application again and rotate the device. Now, if you inspect the Debug log, you will see your messages in the following order: your create message, followed by your destroy message, followed lastly by your create message again. This is because the activity is being created when it first loads, destroyed when the screen is rotated and recreated when the device has finished rotating.</p>
<p>So how do you persist the data during a rotation? The answer to that also lies in an Activity’s life cycle, but requires a bit of work. The keys are a few of the other life cycle methods, <code>onPause()</code> and <code>onResume()</code>. <code>onPause()</code> is called every time an Activity goes out of scope. So anytime an activity gets removed from the view of a user <code>onPause()</code> is called. <code>onResume()</code> is called anytime an Activity comes back into scope, it is also called immediately after a call to <code>onCreate()</code>. But just knowing that <code>onPause()</code> and <code>onResume()</code> exists is not enough. You need to know how to use it properly in order to persist data. The quick and dirty way of achieving our goal is simply to write our text to a file in <code>onPause()</code> and load the data from file in <code>onResume()</code>. Here is an example of how to accomplish this. Keep in mind that this is the <em>wrong</em> way of doing this in a proper application. Instead, you would want to use an MVC architecture and store all of the data applicable to your application in a model when the Activity is destroyed and then simply reference that model when the Activity is re-created. This will save you a lot of overhead because you will not have to write to file every time an Activity goes out of scope. But using a model is an entirely other topic itself, so we will stick to the quick and dirty way for this example.</p>
<div class="highlight"><pre><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onPause</span><span class="o">()</span>
<span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onPause</span><span class="o">();</span>
<span class="n">String</span> <span class="n">message</span> <span class="o">=</span> <span class="s">"Stop... hammer time"</span><span class="o">;</span>
<span class="n">Log</span><span class="o">.</span><span class="na">d</span><span class="o">(</span><span class="s">"Debug: "</span><span class="o">,</span> <span class="n">message</span><span class="o">);</span>
<span class="c1">//Get the current message</span>
<span class="n">String</span> <span class="n">currentMessage</span> <span class="o">=</span> <span class="o">((</span><span class="n">EditText</span><span class="o">)(</span><span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">textbox</span><span class="o">))).</span><span class="na">getText</span><span class="o">().</span><span class="na">toString</span><span class="o">();</span>
<span class="c1">//Save the data in the text box to file</span>
<span class="k">try</span>
<span class="o">{</span>
<span class="n">OutputStreamWriter</span> <span class="n">fileWriter</span> <span class="o">=</span> <span class="k">new</span> <span class="n">OutputStreamWriter</span><span class="o">(</span><span class="n">getBaseContext</span><span class="o">().</span><span class="na">openFileOutput</span><span class="o">(</span><span class="s">"data.txt"</span><span class="o">,</span> <span class="n">Context</span><span class="o">.</span><span class="na">MODE_PRIVATE</span><span class="o">));</span>
<span class="n">fileWriter</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="n">currentMessage</span><span class="o">);</span>
<span class="n">fileWriter</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">catch</span> <span class="o">(</span><span class="n">IOException</span> <span class="n">e</span><span class="o">)</span>
<span class="o">{</span>
<span class="n">Log</span><span class="o">.</span><span class="na">e</span><span class="o">(</span><span class="s">"File Save"</span><span class="o">,</span> <span class="s">"Could not write to the following file: "</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="na">toString</span><span class="o">());</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onResume</span><span class="o">()</span>
<span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onResume</span><span class="o">();</span>
<span class="n">String</span> <span class="n">data</span> <span class="o">=</span> <span class="s">""</span><span class="o">;</span>
<span class="c1">//Load the data from file</span>
<span class="k">try</span>
<span class="o">{</span>
<span class="n">InputStream</span> <span class="n">inputStream</span> <span class="o">=</span> <span class="n">openFileInput</span><span class="o">(</span><span class="s">"data.txt"</span><span class="o">);</span>
<span class="k">if</span> <span class="o">(</span><span class="n">inputStream</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span>
<span class="o">{</span>
<span class="n">InputStreamReader</span> <span class="n">fileInputReader</span> <span class="o">=</span> <span class="k">new</span> <span class="n">InputStreamReader</span><span class="o">(</span><span class="n">inputStream</span><span class="o">);</span>
<span class="n">BufferedReader</span> <span class="n">bufferedFileReader</span> <span class="o">=</span> <span class="k">new</span> <span class="n">BufferedReader</span><span class="o">(</span><span class="n">fileInputReader</span><span class="o">);</span>
<span class="n">String</span> <span class="n">receiveString</span> <span class="o">=</span> <span class="s">""</span><span class="o">;</span>
<span class="n">StringBuilder</span> <span class="n">stringBuilder</span> <span class="o">=</span> <span class="k">new</span> <span class="n">StringBuilder</span><span class="o">();</span>
<span class="k">while</span> <span class="o">((</span><span class="n">receiveString</span> <span class="o">=</span> <span class="n">bufferedFileReader</span><span class="o">.</span><span class="na">readLine</span><span class="o">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span>
<span class="o">{</span>
<span class="n">stringBuilder</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="n">receiveString</span><span class="o">);</span>
<span class="o">}</span>
<span class="n">inputStream</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">stringBuilder</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">catch</span> <span class="o">(</span><span class="n">FileNotFoundException</span> <span class="n">e</span><span class="o">)</span>
<span class="o">{</span>
<span class="n">Log</span><span class="o">.</span><span class="na">e</span><span class="o">(</span><span class="s">"File Loader"</span><span class="o">,</span> <span class="s">"Could not find the file: "</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="na">toString</span><span class="o">());</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">IOException</span> <span class="n">e</span><span class="o">)</span>
<span class="o">{</span>
<span class="n">Log</span><span class="o">.</span><span class="na">e</span><span class="o">(</span><span class="s">"File Loader"</span><span class="o">,</span> <span class="s">"Can not read file: "</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="na">toString</span><span class="o">());</span>
<span class="o">}</span>
<span class="c1">//write the message back into the text box</span>
<span class="n">EditText</span> <span class="n">textBox</span> <span class="o">=</span> <span class="o">(</span><span class="n">EditText</span><span class="o">)(</span><span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">textbox</span><span class="o">));</span>
<span class="n">textBox</span><span class="o">.</span><span class="na">setText</span><span class="o">(</span><span class="n">data</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">(),</span> <span class="mi">0</span><span class="o">,</span> <span class="n">data</span><span class="o">.</span><span class="na">toCharArray</span><span class="o">().</span><span class="na">length</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div>
<p>Congratulations! Your text now persists through device rotation. At this point you are probably despising Android. I mean how can something so simple be so difficult? Well my friends, it’s not. I’m going to fill you in on a little secret and you are probably going to hate me after having done all that file work. Go ahead and comment out the <code>onPause()</code> and <code>onResume()</code> methods and add the following line of code to the EditText attribute in <code>activity_main.xml</code>.</p>
<div class="highlight"><pre><code class="language-xml" data-lang="xml">android:freezesText="true"
</code></pre></div>
<p>Now run your application again and test out rotation. See, I told you that you were going to hate me. So if you could fix this problem with one line of code why did I walk you through this long painful example of using the Activity’s life cycle methods to preserve the text? The reason is so I could fill you with knowledge about life, well knowledge about life cycle that is. Anyone who is aspiring to become an Android developer needs to understand an Activity’s life cycle like the back of their hand, and there is no better way of engraining this into your mind then by making you suffer through a long tedious solution to a simple problem.</p>
<p>Now that you have been painfully introduced to an Activity and it life cycle let’s go-ahead flip the script a little bit and discuss iOS View Controllers.</p>
<h4 id="view-controllers">View Controllers:</h4>
<p>A <a href="https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/index.html-//apple_ref/doc/uid/TP40007457-CH2-SW1">View Controller</a> and an Activity are similar in many ways but have a few key differences. Similar to an Activity, a View Controller is the controller in the MVC architecture. View Controllers are also similar to Activities in the sense that every application must have at least one View Controller and pretty much every application has more than one. The general rule with iOS applications is that every separate screen that is presented to a user should have its own View Controller. The reason for this is because Apple strongly suggests that all applications developed for iOS should follow the MVC architecture. Typically a View Controller manages one view (and all of it’s subviews) associated with it that it uses to display and receive information from the user. Similar to Activities, View Controllers also have a life cycle. However, it does differ slightly from that of an Activity. A View Controller has the following life cycle methods, <code>loadView()</code>, <code>viewDidLoad()</code>, <code>viewWillAppear()</code>, <code>viewDidAppear()</code>, <code>viewWillDisappear()</code>, and <code>viewDidDisappear()</code>. So now that you have had a little background on what a View Controller is, let’s jump into another example doing the same thing we did earlier with our Activity example.</p>
<p>First let’s start by creating a new Single View Application project in Xcode and selecting Swift as the language. You can set the product name as whatever you like, but for my example I am going to use the name ViewControllerExample. Now that we have a new project up and running let’s get rid of all of the storyboard files. For now, we will define our layout programmatically to better understand how the ViewController works. Go ahead and delete the <code>Main.storyboard</code> and the <code>LaunchScreen.storyboard</code> files. Make sure that you select the “remove reference” option for both of these files. After that open up <code>Info.plist</code> and delete the key-value pairs for both the “Launch screen interface file base name” and the “Main storyboard file base name”. Go ahead and run the project. You should see a black screen. If your program crashed go back and make sure that you deleted all of the correct files and key-values from the <code>Info.plist</code>. Now that we have set up our project it’s time to add a text box to the center of our screen. But before we add a text box to our screen we need to set up our window in the App Delegate. The App Delegate is similar to a Main Activity in Android because it is essentially the control center for the application, it is responsible for setting up the application on launch and taking care of application clean up when it enters the background or is destroyed. Navigate to <code>AppDelegate.swift</code> and add the following code to <code>application(application:didFinishLaunchingWithOptions:)</code></p>
<div class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">func</span> <span class="nf">application</span><span class="p">(</span><span class="nv">application</span><span class="p">:</span> <span class="kt">UIApplication</span><span class="p">,</span> <span class="n">didFinishLaunchingWithOptions</span> <span class="nv">launchOptions</span><span class="p">:</span> <span class="p">[</span><span class="kt">NSObject</span><span class="p">:</span> <span class="kt">AnyObject</span><span class="p">]?)</span> <span class="o">-&gt;</span> <span class="kt">Bool</span>
<span class="p">{</span>
<span class="c1">//Make the view Controller</span>
<span class="k">let</span> <span class="nv">viewController</span><span class="p">:</span> <span class="kt">UIViewController</span> <span class="o">=</span> <span class="kt">ViewController</span><span class="p">()</span>
<span class="n">viewController</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">backgroundColor</span> <span class="o">=</span> <span class="kt">UIColor</span><span class="o">.</span><span class="nf">blackColor</span><span class="p">()</span>
<span class="c1">//Set up the window</span>
<span class="n">window</span> <span class="o">=</span> <span class="kt">UIWindow</span><span class="p">()</span>
<span class="n">window</span><span class="p">?</span><span class="o">.</span><span class="n">rootViewController</span> <span class="o">=</span> <span class="n">viewController</span>
<span class="n">window</span><span class="p">?</span><span class="o">.</span><span class="nf">makeKeyAndVisible</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">true</span>
<span class="p">}</span>
</code></pre></div>
<p>Now run your application again. You should still see a black screen. But don’t worry we are getting close to having our text box up and running. Now navigate to <code>ViewContoller.swift</code> and modify <code>viewDidLoad()</code> like so,</p>
<div class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="k">override</span> <span class="kd">func</span> <span class="nf">viewDidLoad</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">super</span><span class="o">.</span><span class="nf">viewDidLoad</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">textField</span><span class="p">:</span> <span class="kt">UITextField</span> <span class="o">=</span> <span class="kt">UITextField</span><span class="p">()</span>
<span class="n">textField</span><span class="o">.</span><span class="n">frame</span> <span class="o">=</span> <span class="kt">CGRectMake</span><span class="p">((</span><span class="n">view</span><span class="o">.</span><span class="n">bounds</span><span class="o">.</span><span class="n">width</span><span class="o">/</span><span class="mi">2</span> <span class="o">-</span> <span class="mi">100</span><span class="p">),</span> <span class="p">(</span><span class="n">view</span><span class="o">.</span><span class="n">bounds</span><span class="o">.</span><span class="n">height</span><span class="o">/</span><span class="mi">2</span> <span class="o">-</span> <span class="mi">20</span><span class="p">),</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
<span class="n">textField</span><span class="o">.</span><span class="n">backgroundColor</span> <span class="o">=</span> <span class="kt">UIColor</span><span class="o">.</span><span class="nf">whiteColor</span><span class="p">()</span>
<span class="n">view</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">textField</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>Now note that we could have put this same code in <code>viewWillAppear()</code> or <code>viewDidAppear()</code> and it would have worked just fine for this simple example. The only difference is that <code>viewDidLoad()</code> is called once after the view controller’s view has been created, and the appear methods are called every time the view controller becomes visible. If we were to add the view in either appear method, a new view would be added every time the view controller became visible (after navigating back from a subsequent screen, for example), which is not what we want because it is extremely inefficient. However, once again keep in mind that even using <code>viewDidLoad()</code> is not the proper way of setting up a view for an iOS application. In a real application you should create your own custom view and add a UITextField to that view and then use <code>loadView()</code> in the ViewController class to load in your custom view. But for this example we will again stick with the quick and dirty way of doing things.</p>
<p>Run your project again. You should now see a white text box in the center of the screen. Now that we finally have a text box up on screen let’s test it out. Let’s do the same thing that we did earlier with our ActivityExample. Let’s enter some text into the text box and change the device orientation (If you are working on a Mac you can rotate the screen by using holding down the command key and pressing either the right or left arrow keys). But before you actually test this out, what you do you expect to happen? Do you think your text will be deleted like in the Activity Example from earlier? Or do you think it will stick around this time? Go ahead and run it so you can find out.</p>
<p>Surprise, the text stuck around like leader of the Brotherhood Without Banners after losing his battle with the Hound. So what caused the text to stick around, the Lord of Light? Well not exactly. Android destroys the Activity to allow you to handle changes in configuration (device orientation, device language) and allows you to load a different layout. In iOS on the other hand, you will need to handle those device configuration changes yourself. If you think about it, it’s extremely inefficient to completely destroy and recreate a View Controller every time that a device is rotated. Of course this implementation does still have its downsides. As you will notice the text box is no longer centered in the screen. The reason for this is because it only lays itself out based on its original portrait screen dimensions when it was first drawn. Orientation changes don’t automatically trigger another layout pass. So how can we fix this? Do we need to override <code>viewWillDisappear()</code> or <code>viewDidDisappear()</code> similar to what we did in the Activity example above? Unfortunately this will not work because the View Controller never disappears during rotation. In fact these methods are only called when a View Controller’s view disappears from the screen. They do not even get called when the application is destroyed. Instead Apple chose to have a single control center take care the clean up that should happen when an application is destroyed, and that control center is AppDelegate. So any calls to file saving methods should be called in the AppDelegate method <code>applicationWillTerminate()</code> rather than in a specific View Controller. So how can we reposition our text box if none of the View Controller’s life cycle methods are called during rotation? Well believe it or not Apple realized this problem and provided us with the method <code>viewWillLayoutSubviews()</code>. To fix this issue elevate textField to an instance variable and add the following code to ViewController.swift</p>
<div class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="k">override</span> <span class="kd">func</span> <span class="nf">viewWillLayoutSubviews</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">textField</span><span class="o">.</span><span class="n">frame</span> <span class="o">=</span> <span class="kt">CGRectMake</span><span class="p">((</span><span class="n">view</span><span class="o">.</span><span class="n">bounds</span><span class="o">.</span><span class="n">width</span><span class="o">/</span><span class="mi">2</span> <span class="o">-</span> <span class="mi">100</span><span class="p">),</span> <span class="p">(</span><span class="n">view</span><span class="o">.</span><span class="n">bounds</span><span class="o">.</span><span class="n">height</span><span class="o">/</span><span class="mi">2</span> <span class="o">-</span> <span class="mi">20</span><span class="p">),</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div>
<p>There, now we have a text box with the correct text located in the center of the screen. But the one thing that I’m sure some of you realized is that we are redrawing the text box on the screen. So won’t this perform just as poorly as the Android implementation of <code>onDestroy()</code>? The answer is sort of. It does have to redraw the view, but it doesn’t have to actually kill the View Controller and re create it like we did in the Activity example above. So for that reason it performs better than the Activity implementation that Google chose.</p>
<h4 id="summary">Summary</h4>
<p>Both examples have their drawbacks and you can see the pros and cons of developing this simple application on both platforms. I’m sure that by now you can start to see how the iOS vs Android battle can become a heated debate pretty quickly because they do similar things but in different fashions. During the remainder of this series I will cover a number of other differences between the two platforms and help you make an informed decision on which platform you think is better. So don’t worry, if you haven’t already picked a side in the Android vs. iOS battle there is still plenty of time left. After all, the Battle of the bOStards is just beginning.</p>
<p>Also keep in mind that there are a number of other differences between Activities and View Controllers, but for the sake of your time and mine I choose to keep this article fairly short and straightforward. If you want to learn more about the differences between the two, check out the official documentation provided by Google and Apple by using the following links.</p>
<ul>
<li>Activities: <a href="https://developer.android.com/guide/components/activities.html">https://developer.android.com/guide/components/activities.html</a></li>
<li>View Controllers: <a href="https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/index.html-//apple_ref/doc/uid/TP40007457-CH2-SW1">https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/index.html-//apple_ref/doc/uid/TP40007457-CH2-SW1</a></li>
</ul>
</description>
<pubDate>Fri, 12 Aug 2016 00:00:00 -0600</pubDate>
<link>http://www.pixio.com/blog/2016-08-12/activities-vs-view-controllers/</link>
<guid isPermaLink="true">http://www.pixio.com/blog/2016-08-12/activities-vs-view-controllers/</guid>
<category>android</category>
<category>ios</category>
<category>programming</category>
</item>
<item>
<title>A Nibble of Gradle Flavors</title>
<description><p>In Android Studio, <a href="https://developer.android.com/studio/build/index.html">Gradle</a> is used as a build tool with the <a href="https://developer.android.com/studio/releases/gradle-plugin.html">Android plugin</a> to configure your project and create an APK. Though most developers use Gradle to build their project, many of them don&#39;t take full advantage of Gradle scripts. One of the most common use cases is creating different <a href="http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.ProductFlavor.html">product flavors</a> for their app. Flavors essentially let you build different versions of your app using a single code base.</p>
<p>While there are a lot of very simple apps that don&#39;t really need different flavors, many developers use the <strong>Demo</strong>/<strong>Paid</strong> paradigm to monetize their applications. Another common useful case is when you have a production server and a staging server, flavors can you help you make apps to use the corresponding server. There&#39;s many reasons why a flavor would be nice or necessary, let&#39;s dive in a little deeper at how easy it is to accomplish this.</p>
<h3 id="which-flavor-is-right-for-you">Which Flavor is right for you?</h3>
<p>To start off, open the <code>build.gradle</code> for the <em>module</em> of your Android project (not the <code>build.gradle</code> for the <em>project</em>). It should look similar to:</p>
<div class="highlight"><pre><code class="language-groovy" data-lang="groovy"><span class="n">apply</span> <span class="nl">plugin:</span> <span class="s1">'com.android.application'</span>
<span class="n">android</span> <span class="o">{</span>
<span class="o">...</span>
<span class="n">defaultConfig</span> <span class="o">{</span>
<span class="n">applicationId</span> <span class="s2">"com.pixio.awesomeapp"</span>
<span class="o">...</span>
<span class="n">versionCode</span> <span class="mi">1</span>
<span class="n">versionName</span> <span class="s2">"1.0"</span>
<span class="o">}</span>
<span class="n">buildTypes</span> <span class="o">{</span>
<span class="o">...</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">...</span>
</code></pre></div>
<p>By adding just a few lines, we can have different flavors.</p>
<div class="highlight"><pre><code class="language-groovy" data-lang="groovy"><span class="n">android</span> <span class="o">{</span>
<span class="o">...</span>
<span class="n">productFlavors</span> <span class="o">{</span>
<span class="n">free</span> <span class="o">{</span>
<span class="n">applicationId</span> <span class="s1">'com.pixio.awesomeapp.free'</span>
<span class="n">resValue</span> <span class="s2">"string"</span><span class="o">,</span> <span class="s2">"app_name"</span><span class="o">,</span> <span class="s2">"Awesome App (FREE)"</span>
<span class="o">}</span>
<span class="n">paid</span> <span class="o">{</span>
<span class="n">applicationId</span> <span class="s1">'com.pixio.awesomeapp.paid'</span>
<span class="n">resValue</span> <span class="s2">"string"</span><span class="o">,</span> <span class="s2">"app_name"</span><span class="o">,</span> <span class="s2">"Awesome app+"</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div>
<p>Simple and easy. As shown above, I have overwritten the name of the app and the application id depending on which flavor is built (<code>app_name</code> is the default field to store the name of the app displayed to the user). Anything that is defined in <code>defaultConfig</code> can be overridden by any/all flavors to further customize the different apps. To actually make use of these newly defined flavors, we need to <strong>sync our project with gradle files</strong> (<em>Tools</em> -&gt; <em>Android</em> -&gt; <em>Sync project with gradle files</em>).</p>
<p>Well now we have our flavors declared, how do we build them? In Android Studio, open the <strong>Build Variants</strong> window (<em>View</em> -&gt; <em>Tool Windows</em> -&gt; <em>Build Variants</em>). If you have synced with gradle, you should now see a window that shows which module you are working with and which <a href="https://developer.android.com/studio/build/build-variants.html">Build Variant</a> you&#39;re working with. If you click on the <em>Build Variant</em> box, a dropdown will appear letting you pick the <code>Debug</code> and <code>Release</code> build types of your defined flavors. These build types can each be combined with each flavor to determine which keystore will be used when signing your apk during the build process. Generally, you&#39;ll want to work with the <code>Debug</code> variant when developing and the <code>Release</code> variant when building an APK for beta testing and the Play Store.</p>
<h3 id="build-config">Build Config</h3>
<p>With the different flavors now set up, we can customize the app&#39;s behavior even further by adding new [build config fields][build-config]. These fields are added in the same <code>build.gradle</code> that we&#39;ve been working in, and can be added to flavors as well as build types. We can define unique values by adding lines like the following to any flavor:</p>
<div class="highlight"><pre><code class="language-groovy" data-lang="groovy"><span class="n">buildConfigField</span> <span class="s1">'String'</span><span class="o">,</span> <span class="s1">'HOST'</span><span class="o">,</span> <span class="s1">'"staging.pixioserver.com"'</span>
</code></pre></div>
<p>With that specific example, we defined <code>BuildConfig.HOST</code> to have the value <code>&quot;staging.pixioserver.com</code>. This allows us to have a specific endpoint for our staging flavor app that is different from the release version, which points to some production endpoint. Then, by building our app in the corresponding <code>Staging</code> and <code>Production</code> versions, we get the server intended for that app.</p>
<p>We can add any valid java type as a <code>buildConfigField</code> with any valid java variable name. This could be useful for defining specific flavors/variants that need to report bug crashes or to not allow certain features using boolean flags. For example, you can enable a feature that let’s you view server logs or debug data in certain debugging/client versions of the app.</p>
<h3 id="that-39-s-a-gradle-wrap">That&#39;s A (Gradle) Wrap!</h3>
<p>This was just a small touch of the power you can use when customizing your <code>build.gradle</code>. A sample of things you can do are set your project up to automatically sign the apk with a specified keystore, defining custom build procedures when compiling the project, or even modifying the apk after building to include the version number. Using these concepts we can define custom flavors to achieve multiple Android apps using the <em>same</em> codebase. By using flavors, we can specify special <code>buildConfigField</code> properties that further define the behavior of each app and let developers have more control over testing/paid/branded versions. With a little more work, you can actually have code separated into different <a href="https://developer.android.com/studio/build/build-variants.html#sourcesets">source sets</a> that allow you to control the flow of your app with finer control by executing code blocks for corresponding flavors.</p>
<p>[build-config]: <http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.ProductFlavor.html#com.android.build.gradle.internal.dsl.ProductFlavor:buildConfigField(java.lang.String, java.lang.String, java.lang.String)></p>
</description>
<pubDate>Fri, 05 Aug 2016 00:00:00 -0600</pubDate>
<link>http://www.pixio.com/blog/2016-08-05/a-nibble-of-gradle-flavors/</link>
<guid isPermaLink="true">http://www.pixio.com/blog/2016-08-05/a-nibble-of-gradle-flavors/</guid>
<category>android</category>
<category>gradle</category>
<category>programming</category>
</item>
<item>
<title>Wrap Battle: Wrapping C with Swift and Java</title>
<description><p>There are many situations in which a shared codebase is desirable. Perhaps your project involves a lot of calculations which you want to be carried out by the exact same code on all your platforms to ensure that the results are identical. Maybe you inherited a large C/C++ codebase or rely on a library that needs to work in your iOS or Android apps and rewriting it is not an option. You might simply prefer to write the bulk of your code in a shared language so that you aren&#39;t testing and validating the same functions in two or more languages.</p>
<p>In this article I present two approaches to wrapping the functionality of a C interface in Swift and Java, highlighting what does and does not work well for each language. The techniques presented below are not the only ways to accomplish what I set out to do, but they are the most common wrapping styles I have encountered, which is why I chose them over other approaches. The code I present here is also relatively free of &quot;magic tricks&quot; that optimize the code&#39;s efficiency at the expense of immediate readability, so don&#39;t go and use this code as the basis for your next high-performance math library without refining it a bit.</p>
<p>We have written a lot lately about the design of <a href="http://pixio.com/blog/2016-06-03/c-in-the-21st-century/" title="C in the 21st Century">shared object systems</a> and <a href="http://pixio.com/blog/2016-07-08/how-to-score-big-with-androids-ndk/" title="How to Score Big with Android&#39;s NDK">JNI integration for C on Android</a>, so I won&#39;t re-tread that ground here. If you are curious about how to set up a project in either Android Studio or Xcode to do what I describe in this article, look at those earlier articles and/or feel free to check out the <a href="https://github.com/Dave-Heyborne/WrapBattle" title="WrapBattle GitHub Repository">the example repository</a> for this article. Also, note that the code presented below is a subset of the code in the example repository - many code sections were left out of the article for clarity&#39;s sake.</p>
<h2 id="c-library">C Library</h2>
<p>To get started, I will cover the C library I plan to wrap. First is the &#39;data object&#39; in question - a 3D vector represented as a struct:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">CVector3D</span> <span class="p">{</span>
<span class="kt">double</span> <span class="n">x</span><span class="p">;</span>
<span class="kt">double</span> <span class="n">y</span><span class="p">;</span>
<span class="kt">double</span> <span class="n">z</span><span class="p">;</span>
<span class="p">}</span> <span class="n">CVector3D</span><span class="p">;</span>
</code></pre></div>
<p>This is a very simple struct to use, either by directly instantiating it on the stack or by using a convenience constructor that returns a pointer to a heap-allocated struct:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="c1">// Stack Construction
</span><span class="k">const</span> <span class="n">CVector3D</span> <span class="n">vector</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="p">};</span>
<span class="c1">// Pointer Constructor
</span><span class="n">__attribute__</span> <span class="p">((</span><span class="n">malloc</span><span class="p">,</span> <span class="n">nothrow</span><span class="p">,</span> <span class="n">returns_nonnull</span><span class="p">,</span> <span class="n">warn_unused_result</span><span class="p">))</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="n">CVector3DCreate_P</span><span class="p">(</span><span class="k">const</span> <span class="kt">double</span> <span class="n">x</span><span class="p">,</span> <span class="k">const</span> <span class="kt">double</span> <span class="n">y</span><span class="p">,</span> <span class="k">const</span> <span class="kt">double</span> <span class="n">z</span><span class="p">)</span> <span class="p">{</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">vector</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">CVector3D</span><span class="p">));</span>
<span class="n">vector</span><span class="o">-&gt;</span><span class="n">x</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span>
<span class="n">vector</span><span class="o">-&gt;</span><span class="n">y</span> <span class="o">=</span> <span class="n">y</span><span class="p">;</span>
<span class="n">vector</span><span class="o">-&gt;</span><span class="n">z</span> <span class="o">=</span> <span class="n">z</span><span class="p">;</span>
<span class="k">return</span> <span class="n">vector</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Pointer Construction
</span><span class="k">const</span> <span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">vectorPointer</span> <span class="o">=</span> <span class="n">CVector3DCreate_P</span><span class="p">(</span><span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="p">);</span>
</code></pre></div>
<p>Once an instance of the struct has been obtained, it can be manipulated with some simple functions (for example, the cross product function):</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="c1">// Pass-By-Value Cross Product
</span><span class="n">__attribute__</span> <span class="p">((</span><span class="k">const</span><span class="p">,</span> <span class="n">nothrow</span><span class="p">,</span> <span class="n">warn_unused_result</span><span class="p">))</span>
<span class="n">CVector3D</span> <span class="n">CVector3DCrossProduct</span><span class="p">(</span><span class="k">const</span> <span class="n">CVector3D</span> <span class="n">left</span><span class="p">,</span> <span class="k">const</span> <span class="n">CVector3D</span> <span class="n">right</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="k">const</span> <span class="n">CVector3D</span><span class="p">){(</span><span class="n">left</span><span class="p">.</span><span class="n">y</span> <span class="o">*</span> <span class="n">right</span><span class="p">.</span><span class="n">z</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">left</span><span class="p">.</span><span class="n">z</span> <span class="o">*</span> <span class="n">right</span><span class="p">.</span><span class="n">y</span><span class="p">),</span>
<span class="p">(</span><span class="n">left</span><span class="p">.</span><span class="n">z</span> <span class="o">*</span> <span class="n">right</span><span class="p">.</span><span class="n">x</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">left</span><span class="p">.</span><span class="n">x</span> <span class="o">*</span> <span class="n">right</span><span class="p">.</span><span class="n">z</span><span class="p">),</span>
<span class="p">(</span><span class="n">left</span><span class="p">.</span><span class="n">x</span> <span class="o">*</span> <span class="n">right</span><span class="p">.</span><span class="n">y</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">left</span><span class="p">.</span><span class="n">y</span> <span class="o">*</span> <span class="n">right</span><span class="p">.</span><span class="n">x</span><span class="p">)};</span>
<span class="p">}</span>
<span class="c1">// Pass-By-Pointer Cross product
</span><span class="n">__attribute__</span> <span class="p">((</span><span class="n">malloc</span><span class="p">,</span> <span class="n">nonnull</span><span class="p">,</span> <span class="n">nothrow</span><span class="p">,</span> <span class="n">returns_nonnull</span><span class="p">,</span> <span class="n">warn_unused_result</span><span class="p">))</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="n">CVector3DCrossProduct_P</span><span class="p">(</span><span class="k">const</span> <span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">left</span><span class="p">,</span> <span class="k">const</span> <span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">right</span><span class="p">)</span> <span class="p">{</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">crossProduct</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">CVector3D</span><span class="p">));</span>
<span class="n">crossProduct</span><span class="o">-&gt;</span><span class="n">x</span> <span class="o">=</span> <span class="p">(</span><span class="n">left</span><span class="o">-&gt;</span><span class="n">y</span> <span class="o">*</span> <span class="n">right</span><span class="o">-&gt;</span><span class="n">z</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">left</span><span class="o">-&gt;</span><span class="n">z</span> <span class="o">*</span> <span class="n">right</span><span class="o">-&gt;</span><span class="n">y</span><span class="p">);</span>
<span class="n">crossProduct</span><span class="o">-&gt;</span><span class="n">y</span> <span class="o">=</span> <span class="p">(</span><span class="n">left</span><span class="o">-&gt;</span><span class="n">z</span> <span class="o">*</span> <span class="n">right</span><span class="o">-&gt;</span><span class="n">x</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">left</span><span class="o">-&gt;</span><span class="n">x</span> <span class="o">*</span> <span class="n">right</span><span class="o">-&gt;</span><span class="n">z</span><span class="p">);</span>
<span class="n">crossProduct</span><span class="o">-&gt;</span><span class="n">z</span> <span class="o">=</span> <span class="p">(</span><span class="n">left</span><span class="o">-&gt;</span><span class="n">x</span> <span class="o">*</span> <span class="n">right</span><span class="o">-&gt;</span><span class="n">y</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">left</span><span class="o">-&gt;</span><span class="n">y</span> <span class="o">*</span> <span class="n">right</span><span class="o">-&gt;</span><span class="n">x</span><span class="p">);</span>
<span class="k">return</span> <span class="n">crossProduct</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>All of this should be fairly straightforward. But how can this code be effectively wrapped by Swift and Java for use in mobile applications? Two common approaches to doing this are either making wrapper classes that internally hold a reference to a C struct, or trying to replicate the struct directly in the target language (generally performing a conversion to pass the struct into C functions that expect value parameters). As will be shown below, these techniques differ greatly in how useful and simple they are between Swift and Java.</p>
<h2 id="swift-wrappers">Swift Wrappers</h2>
<p>To start, here are the Swift implementations of each wrapper paradigm, starting with the value wrapper:</p>
<div class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="c1">// Value 'Wrapper'</span>
<span class="kd">extension</span> <span class="kt">CVector3D</span> <span class="p">{</span>
<span class="k">mutating</span> <span class="kd">func</span> <span class="nf">add</span><span class="p">(</span><span class="nv">other</span><span class="p">:</span> <span class="kt">CVector3D</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span> <span class="o">=</span> <span class="kt">CVector3DAdd</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nf">crossProduct</span><span class="p">(</span><span class="nv">other</span><span class="p">:</span> <span class="kt">CVector3D</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">CVector3D</span> <span class="p">{</span>
<span class="k">return</span> <span class="kt">CVector3DCrossProduct</span><span class="p">(</span><span class="k">self</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Notice that this is, in fact, not a wrapper class at all, but rather an extension on the C struct directly. Because C is (mostly) seamlessly bridged into Swift, it is possible to use non-opaque C structs directly in Swift code as though they were regular Swift structs.</p>
<p>That being said, many libraries manipulate struct instances &quot;by reference&quot; via pointers to heap-allocated memory, rather than by modifying and passing around structs by value. Oftentimes these pointers are also opaque and the struct definition is not visible from the library&#39;s interface, so even if you wanted to use the structs by value in Swift, you couldn&#39;t. Below is the implementation of a Swift class that wraps a pointer to a C vector:</p>
<div class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="c1">// Pointer Wrapper</span>
<span class="kd">final</span> <span class="kd">class</span> <span class="kt">Vector3D</span> <span class="p">{</span>
<span class="kd">private</span> <span class="k">var</span> <span class="nv">reference</span><span class="p">:</span> <span class="kt">UnsafeMutablePointer</span><span class="o">&lt;</span><span class="kt">CVector3D</span><span class="o">&gt;</span>
<span class="nf">init</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="kt">CDouble</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="kt">CDouble</span><span class="p">,</span> <span class="nv">z</span><span class="p">:</span> <span class="kt">CDouble</span><span class="p">)</span> <span class="p">{</span>
<span class="n">reference</span> <span class="o">=</span> <span class="kt">CVector3DCreate_P</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">private</span> <span class="nf">init</span><span class="p">(</span><span class="nv">reference</span><span class="p">:</span> <span class="kt">UnsafeMutablePointer</span><span class="o">&lt;</span><span class="kt">CVector3D</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">reference</span> <span class="o">=</span> <span class="n">reference</span>
<span class="p">}</span>
<span class="kd">deinit</span> <span class="p">{</span>
<span class="kt">CVector3DDestroy_P</span><span class="p">(</span><span class="n">reference</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">var</span> <span class="nv">x</span><span class="p">:</span> <span class="kt">CDouble</span> <span class="p">{</span>
<span class="k">get</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">reference</span><span class="o">.</span><span class="n">pointee</span><span class="o">.</span><span class="n">x</span>
<span class="p">}</span>
<span class="k">set</span> <span class="p">{</span>
<span class="n">reference</span><span class="o">.</span><span class="n">pointee</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">newValue</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">var</span> <span class="nv">y</span><span class="p">:</span> <span class="kt">CDouble</span> <span class="p">{</span>
<span class="k">get</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">reference</span><span class="o">.</span><span class="n">pointee</span><span class="o">.</span><span class="n">y</span>
<span class="p">}</span>
<span class="k">set</span> <span class="p">{</span>
<span class="n">reference</span><span class="o">.</span><span class="n">pointee</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">newValue</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">var</span> <span class="nv">z</span><span class="p">:</span> <span class="kt">CDouble</span> <span class="p">{</span>
<span class="k">get</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">reference</span><span class="o">.</span><span class="n">pointee</span><span class="o">.</span><span class="n">z</span>
<span class="p">}</span>
<span class="k">set</span> <span class="p">{</span>
<span class="n">reference</span><span class="o">.</span><span class="n">pointee</span><span class="o">.</span><span class="n">z</span> <span class="o">=</span> <span class="n">newValue</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nf">add</span><span class="p">(</span><span class="nv">other</span><span class="p">:</span> <span class="kt">Vector3D</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">CVector3DAdd_P</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">reference</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nf">crossProduct</span><span class="p">(</span><span class="nv">other</span><span class="p">:</span> <span class="kt">Vector3D</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Vector3D</span> <span class="p">{</span>
<span class="k">return</span> <span class="kt">Vector3D</span><span class="p">(</span><span class="nv">reference</span><span class="p">:</span> <span class="kt">CVector3DCrossProduct_P</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">reference</span><span class="p">))</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Notice the extra infrastructure above that deals with keeping a reference to a pointer, and the <code>deinit</code> function which ensures that the memory associated with the pointer is freed once the Swift object is deallocated. A private init function is also needed to create new <code>Vector3D</code> wrappers for the return values of C functions that return pointers to new <code>CVector3D</code>s. The struct extension didn&#39;t have to account for manual memory management (because the by-value struct functions don&#39;t allocate heap memory) or wrapping return values, so the wrapper class feels distinctly inferior.</p>
<p>Below are some examples of using each of the above vector implementations:</p>
<div class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="c1">// Value 'Wrapper' Usage</span>
<span class="k">var</span> <span class="nv">cVector3D</span><span class="p">:</span> <span class="kt">CVector3D</span> <span class="o">=</span> <span class="kt">CVector3D</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nv">z</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">)</span>
<span class="n">cVector3D</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="nv">other</span><span class="p">:</span> <span class="kt">CVector3D</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nv">z</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">))</span>
<span class="c1">// Pointer Wrapper Usage</span>
<span class="k">let</span> <span class="nv">vector3D</span><span class="p">:</span> <span class="kt">Vector3D</span> <span class="o">=</span> <span class="kt">Vector3D</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nv">z</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">)</span>
<span class="n">vector3D</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="nv">other</span><span class="p">:</span> <span class="kt">Vector3D</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="nv">z</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">))</span>
</code></pre></div>
<p>As you can see, both wrapper methods are quite simple and using the resulting implementations feels similar. However, the struct extension is (in my opinion) the clear winner of the two strategies for Swift if the programmer has access to the struct definition. It does not introduce a new type, directly uses the existing C functions with no modification, and doesn&#39;t necessitate any kind of memory management or boxing/unboxing on the part of the implementer.</p>
<h2 id="java-wrappers">Java Wrappers</h2>
<p>Moving on to the Java side, here is the Java implementation of a value wrapper for the <code>CVector3D</code> struct, which tries to get as close as Java allows to having a &quot;struct&quot; (but due to the fact that it is actually a class, it won&#39;t actually work as a struct in Java the way that it does in Swift).</p>
<div class="highlight"><pre><code class="language-java" data-lang="java"><span class="c1">// 'Value' Wrapper</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Vector3DStruct</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="n">x</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="n">y</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="n">z</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Vector3DStruct</span><span class="o">(</span><span class="kt">double</span> <span class="n">x</span><span class="o">,</span> <span class="kt">double</span> <span class="n">y</span><span class="o">,</span> <span class="kt">double</span> <span class="n">z</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">x</span> <span class="o">=</span> <span class="n">x</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">y</span> <span class="o">=</span> <span class="n">y</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">z</span> <span class="o">=</span> <span class="n">z</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="nf">getX</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">x</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setX</span><span class="o">(</span><span class="kt">double</span> <span class="n">x</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">x</span> <span class="o">=</span> <span class="n">x</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="nf">getY</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">y</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setY</span><span class="o">(</span><span class="kt">double</span> <span class="n">y</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">y</span> <span class="o">=</span> <span class="n">y</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">double</span> <span class="nf">getZ</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">z</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setZ</span><span class="o">(</span><span class="kt">double</span> <span class="n">z</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">z</span> <span class="o">=</span> <span class="n">z</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="kt">void</span> <span class="nf">add</span><span class="o">(</span><span class="n">Vector3DStruct</span> <span class="n">other</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="n">Vector3DStruct</span> <span class="nf">crossProduct</span><span class="o">(</span><span class="n">Vector3DStruct</span> <span class="n">other</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div>
<p>Since Java does not natively support C structs, the struct is almost entirely rewritten to support interacting with it as a Java object. Unlike a &quot;real&quot; struct, this Java object will not be treated as a value type, meaning that if one is modified within a function the changes will persist outside the function. The class methods marked with the <code>native</code> keyword are implemented on the C side via the JNI, as shown below:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="n">JNIEXPORT</span> <span class="kt">void</span> <span class="n">JNICALL</span>
<span class="nf">Java_com_pixio_dave_Vectors_Vector3DStruct_add</span><span class="p">(</span><span class="n">JNIEnv</span><span class="o">*</span> <span class="k">const</span> <span class="n">env</span><span class="p">,</span> <span class="k">const</span> <span class="n">jobject</span> <span class="n">instance</span><span class="p">,</span> <span class="k">const</span> <span class="n">jobject</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span>
<span class="k">const</span> <span class="n">jclass</span> <span class="n">Vector3D1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetObjectClass</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">xID1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"x"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">yID1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"y"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">zID1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"z"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">x1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">xID1</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">y1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">yID1</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">z1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">zID1</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jclass</span> <span class="n">Vector3D2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetObjectClass</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">xID2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D2</span><span class="p">,</span> <span class="s">"x"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">yID2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D2</span><span class="p">,</span> <span class="s">"y"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">zID2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D2</span><span class="p">,</span> <span class="s">"z"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">x2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">,</span> <span class="n">xID2</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">y2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">,</span> <span class="n">yID2</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">z2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">,</span> <span class="n">zID2</span><span class="p">);</span>
<span class="k">const</span> <span class="n">CVector3D</span> <span class="n">result</span> <span class="o">=</span> <span class="n">CVector3DAdd</span><span class="p">((</span><span class="k">const</span> <span class="n">CVector3D</span><span class="p">){</span><span class="n">x1</span><span class="p">,</span> <span class="n">y1</span><span class="p">,</span> <span class="n">z1</span><span class="p">},</span> <span class="p">(</span><span class="k">const</span> <span class="n">CVector3D</span><span class="p">){</span><span class="n">x2</span><span class="p">,</span> <span class="n">y2</span><span class="p">,</span> <span class="n">z2</span><span class="p">});</span>
<span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">SetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">xID1</span><span class="p">,</span> <span class="n">result</span><span class="p">.</span><span class="n">x</span><span class="p">);</span>
<span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">SetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">yID1</span><span class="p">,</span> <span class="n">result</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
<span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">SetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">zID1</span><span class="p">,</span> <span class="n">result</span><span class="p">.</span><span class="n">z</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">JJNIEXPORT</span> <span class="n">jobject</span> <span class="n">JNICALL</span>
<span class="nf">Java_com_pixio_dave_Vectors_Vector3DStruct_crossProduct</span><span class="p">(</span><span class="n">JNIEnv</span><span class="o">*</span> <span class="k">const</span> <span class="n">env</span><span class="p">,</span> <span class="k">const</span> <span class="n">jobject</span> <span class="n">instance</span><span class="p">,</span> <span class="k">const</span> <span class="n">jobject</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span>
<span class="k">const</span> <span class="n">jclass</span> <span class="n">Vector3D1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetObjectClass</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">xID1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"x"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">yID1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"y"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">zID1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"z"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">x1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">xID1</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">y1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">yID1</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">z1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">zID1</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jclass</span> <span class="n">Vector3D2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetObjectClass</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">xID2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D2</span><span class="p">,</span> <span class="s">"x"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">yID2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D2</span><span class="p">,</span> <span class="s">"y"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">zID2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D2</span><span class="p">,</span> <span class="s">"z"</span><span class="p">,</span> <span class="s">"D"</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">x2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">,</span> <span class="n">xID2</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">y2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">,</span> <span class="n">yID2</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">double</span> <span class="n">z2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetDoubleField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">,</span> <span class="n">zID2</span><span class="p">);</span>
<span class="k">const</span> <span class="n">CVector3D</span> <span class="n">result</span> <span class="o">=</span> <span class="n">CVector3DCrossProduct</span><span class="p">((</span><span class="k">const</span> <span class="n">CVector3D</span><span class="p">){</span><span class="n">x1</span><span class="p">,</span> <span class="n">y1</span><span class="p">,</span> <span class="n">z1</span><span class="p">},</span> <span class="p">(</span><span class="k">const</span> <span class="n">CVector3D</span><span class="p">){</span><span class="n">x2</span><span class="p">,</span> <span class="n">y2</span><span class="p">,</span> <span class="n">z2</span><span class="p">});</span>
<span class="k">const</span> <span class="n">jmethodID</span> <span class="n">constructor</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetMethodID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"&lt;init&gt;"</span><span class="p">,</span> <span class="s">"(DDD)V"</span><span class="p">);</span>
<span class="k">return</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">NewObject</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="n">constructor</span><span class="p">,</span> <span class="n">result</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">result</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">result</span><span class="p">.</span><span class="n">z</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>Constructing three new vectors just to add one vector to another is, to put it mildly, not great. While some of the class lookup code could be optimized here, the primary problem is that every time a C pass-by-value function needs to be called on the Java object &quot;struct&quot;&#39;, an actual C struct has to be built from that Java object. While the <code>CVector3D</code> struct may not be complex enough to make this operation prohibitively expensive, a more complicated struct would quickly rule out using the above sort of wrapper due to the incredibly wasteful process of round-tripping a Java object into a C struct and then back into a Java object again. It would be far more efficient to simply rewrite the class in pure Java or rewrite the C functions in the JNI layer rather than do all the boxing and unboxing of C structs shown here.</p>
<p>Here is the way that the pointer/reference wrapper class is implemented in Java:</p>
<div class="highlight"><pre><code class="language-java" data-lang="java"><span class="c1">// Pointer Wrapper</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Vector3DPointer</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kt">long</span> <span class="n">reference</span><span class="o">;</span>
<span class="kd">public</span> <span class="nf">Vector3DPointer</span><span class="o">(</span><span class="kt">double</span> <span class="n">x</span><span class="o">,</span> <span class="kt">double</span> <span class="n">y</span><span class="o">,</span> <span class="kt">double</span> <span class="n">z</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">reference</span> <span class="o">=</span> <span class="n">Vector3DPointer</span><span class="o">.</span><span class="na">createReference</span><span class="o">(</span><span class="n">x</span><span class="o">,</span> <span class="n">y</span><span class="o">,</span> <span class="n">z</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="nf">Vector3DPointer</span><span class="o">(</span><span class="kt">long</span> <span class="n">reference</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">reference</span> <span class="o">=</span> <span class="n">reference</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">finalize</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">Throwable</span> <span class="o">{</span>
<span class="n">Vector3DPointer</span><span class="o">.</span><span class="na">destroyReference</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">reference</span><span class="o">);</span>
<span class="kd">super</span><span class="o">.</span><span class="na">finalize</span><span class="o">();</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="kt">double</span> <span class="nf">getX</span><span class="o">();</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="kt">void</span> <span class="nf">setX</span><span class="o">(</span><span class="kt">double</span> <span class="n">x</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="kt">double</span> <span class="nf">getY</span><span class="o">();</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="kt">void</span> <span class="nf">setY</span><span class="o">(</span><span class="kt">double</span> <span class="n">y</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="kt">double</span> <span class="nf">getZ</span><span class="o">();</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="kt">void</span> <span class="nf">setZ</span><span class="o">(</span><span class="kt">double</span> <span class="n">z</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="kt">void</span> <span class="nf">add</span><span class="o">(</span><span class="n">Vector3DPointer</span> <span class="n">other</span><span class="o">);</span>
<span class="kd">public</span> <span class="kd">native</span> <span class="n">Vector3DPointer</span> <span class="nf">crossProduct</span><span class="o">(</span><span class="n">Vector3DPointer</span> <span class="n">other</span><span class="o">);</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">native</span> <span class="kt">long</span> <span class="nf">createReference</span><span class="o">(</span><span class="kt">double</span> <span class="n">x</span><span class="o">,</span> <span class="kt">double</span> <span class="n">y</span><span class="o">,</span> <span class="kt">double</span> <span class="n">z</span><span class="o">);</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kd">native</span> <span class="kt">void</span> <span class="nf">destroyReference</span><span class="o">(</span><span class="kt">long</span> <span class="n">reference</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div>
<p>This wrapper class looks quite similar to the Swift pointer wrapper class, and behaves similarly. A pointer is stored internally as a <code>long</code>, and the Java object&#39;s <code>finalize()</code> method ensures that the memory associated with the pointer is freed when the Java object is about to be deallocated. Here are some of the JNI functions that back the native calls in the class above:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="n">JNIEXPORT</span> <span class="kt">void</span> <span class="n">JNICALL</span>
<span class="nf">Java_com_pixio_dave_Vectors_Vector3DPointer_setX</span><span class="p">(</span><span class="n">JNIEnv</span><span class="o">*</span> <span class="k">const</span> <span class="n">env</span><span class="p">,</span> <span class="k">const</span> <span class="n">jobject</span> <span class="n">instance</span><span class="p">,</span> <span class="k">const</span> <span class="n">jdouble</span> <span class="n">x</span><span class="p">)</span> <span class="p">{</span>
<span class="k">const</span> <span class="n">jclass</span> <span class="n">Vector3D</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetObjectClass</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">referenceID</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D</span><span class="p">,</span> <span class="s">"reference"</span><span class="p">,</span> <span class="s">"J"</span><span class="p">);</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">reference</span> <span class="o">=</span> <span class="p">(</span><span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span><span class="p">)((</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetLongField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">referenceID</span><span class="p">));</span>
<span class="n">reference</span><span class="o">-&gt;</span><span class="n">x</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">JNIEXPORT</span> <span class="kt">void</span> <span class="n">JNICALL</span>
<span class="nf">Java_com_pixio_dave_Vectors_Vector3DPointer_add</span><span class="p">(</span><span class="n">JNIEnv</span><span class="o">*</span> <span class="k">const</span> <span class="n">env</span><span class="p">,</span> <span class="k">const</span> <span class="n">jobject</span> <span class="n">instance</span><span class="p">,</span> <span class="k">const</span> <span class="n">jobject</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span>
<span class="k">const</span> <span class="n">jclass</span> <span class="n">Vector3D1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetObjectClass</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">referenceID1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"reference"</span><span class="p">,</span> <span class="s">"J"</span><span class="p">);</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">reference1</span> <span class="o">=</span> <span class="p">(</span><span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span><span class="p">)((</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetLongField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">referenceID1</span><span class="p">));</span>
<span class="k">const</span> <span class="n">jclass</span> <span class="n">Vector3D2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetObjectClass</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">referenceID2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D2</span><span class="p">,</span> <span class="s">"reference"</span><span class="p">,</span> <span class="s">"J"</span><span class="p">);</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">reference2</span> <span class="o">=</span> <span class="p">(</span><span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span><span class="p">)((</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetLongField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">,</span> <span class="n">referenceID2</span><span class="p">));</span>
<span class="n">CVector3DAdd_P</span><span class="p">(</span><span class="n">reference1</span><span class="p">,</span> <span class="n">reference2</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">JNIEXPORT</span> <span class="n">jobject</span> <span class="n">JNICALL</span>
<span class="nf">Java_com_pixio_dave_Vectors_Vector3DPointer_crossProduct</span><span class="p">(</span><span class="n">JNIEnv</span><span class="o">*</span> <span class="k">const</span> <span class="n">env</span><span class="p">,</span> <span class="k">const</span> <span class="n">jobject</span> <span class="n">instance</span><span class="p">,</span> <span class="k">const</span> <span class="n">jobject</span> <span class="n">other</span><span class="p">)</span> <span class="p">{</span>
<span class="k">const</span> <span class="n">jclass</span> <span class="n">Vector3D1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetObjectClass</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">referenceID1</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"reference"</span><span class="p">,</span> <span class="s">"J"</span><span class="p">);</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">reference1</span> <span class="o">=</span> <span class="p">(</span><span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span><span class="p">)((</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetLongField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">referenceID1</span><span class="p">));</span>
<span class="k">const</span> <span class="n">jclass</span> <span class="n">Vector3D2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetObjectClass</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jfieldID</span> <span class="n">referenceID2</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetFieldID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D2</span><span class="p">,</span> <span class="s">"reference"</span><span class="p">,</span> <span class="s">"J"</span><span class="p">);</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">reference2</span> <span class="o">=</span> <span class="p">(</span><span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span><span class="p">)((</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetLongField</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">other</span><span class="p">,</span> <span class="n">referenceID2</span><span class="p">));</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="k">const</span> <span class="n">result</span> <span class="o">=</span> <span class="n">CVector3DCrossProduct_P</span><span class="p">(</span><span class="n">reference1</span><span class="p">,</span> <span class="n">reference2</span><span class="p">);</span>
<span class="k">const</span> <span class="n">jmethodID</span> <span class="n">constructor</span> <span class="o">=</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">GetMethodID</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="s">"&lt;init&gt;"</span><span class="p">,</span> <span class="s">"(J)V"</span><span class="p">);</span>
<span class="k">return</span> <span class="p">(</span><span class="o">*</span><span class="n">env</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">NewObject</span><span class="p">(</span><span class="n">env</span><span class="p">,</span> <span class="n">Vector3D1</span><span class="p">,</span> <span class="n">constructor</span><span class="p">,</span> <span class="p">(</span><span class="n">jlong</span><span class="p">)</span><span class="n">result</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>The JNI pass-by-pointer methods essentially just have to obtain the pointers from the Java object and then call the C pass-by-pointer functions to carry out their work. Because the Java object here only holds a pointer to the struct rather than the data of the struct itself, changes to the struct can be carried out much more easily and without making the redundant copies seen in the pass-by-value approach. To more directly compare the pass-by-value and pass-by-pointer approaches for Java, look at the following excerpts from the JNI methods below:</p>
<div class="highlight"><pre><code class="language-java" data-lang="java"><span class="c1">// Critical Section of Pass-By-Value JNI Method</span>
<span class="kd">const</span> <span class="n">CVector3D</span> <span class="n">result</span> <span class="o">=</span> <span class="n">CVector3DCrossProduct</span><span class="o">((</span><span class="kd">const</span> <span class="n">CVector3D</span><span class="o">){</span><span class="n">x1</span><span class="o">,</span> <span class="n">y1</span><span class="o">,</span> <span class="n">z1</span><span class="o">},</span> <span class="o">(</span><span class="kd">const</span> <span class="n">CVector3D</span><span class="o">){</span><span class="n">x2</span><span class="o">,</span> <span class="n">y2</span><span class="o">,</span> <span class="n">z2</span><span class="o">});</span>
<span class="c1">// Critical Section of Pass-By-Pointer JNI Method</span>
<span class="n">CVector3D</span><span class="o">*</span> <span class="kd">const</span> <span class="n">result</span> <span class="o">=</span> <span class="n">CVector3DCrossProduct_P</span><span class="o">(</span><span class="n">reference1</span><span class="o">,</span> <span class="n">reference2</span><span class="o">);</span>
</code></pre></div>
<p>Again, notice that the pass-by-value function is rebuilding C structs to pass them into the C function, while the pass-by-pointer function only passes in pointer values. While in this example a 3-element struct might not be far worse than a pointer in terms of overhead, it should be easy to imagine how awful the pass-by-value approach could become as the number and complexity of items in the struct increased. No matter how complicated the struct became, the pass-by-pointer approach is only going to pass a single pointer.</p>
<h2 id="conclusions">Conclusions</h2>
<p>As I mentioned before, the examples above are not the only way of wrapping C structs and their functionality in Swift or Java. However, even these two examples clearly show that the optimal process is significantly different between those two languages. Even if the above code were carefully optimized, my preference for how to wrap C on the Swift side would differ from my preference on the Java side. Swift&#39;s support for C structs natively makes it almost a no-brainer to use the structs by value and add capabilities via extensions (unless pass-by-reference behavior is desired on the Swift side). In fact, Apple has been doing exactly this to enhance their C APIs for use with Swift. Java&#39;s lack of such support means that wrapping a pointer in a Java class ends up being much cleaner, as it does not require a lot of reimplementation of object structure on the Java side.</p>
<p>While wrapping C on either Swift or Java is relatively straightforward, wrapping the same C code in Swift AND Java simultaneously takes a lot more effort. The pointer wrapper approach is generally the superior option of the two I have presented if both Swift and Java require support, because the value wrapper approach can quickly become prohibitively inefficient on the Java side. An even better option, assuming that total control of the C codebase is possible, is to engineer the C library in such a way that Swift and Java tie-ins are part of the design from the start. The C code in this article was deliberately designed to implement two different versions of the same functionality - in reality, one of those sets of functions (pass-by-value or pass-by-pointer) could have been reworked to depend on the other to reduce duplication, and the way the data was being manipulated could have been designed in a more Java-friendly way. These sorts of optimizations are best suited to a future article, but are important to mention, and to consider if you decide to start implementing a shared library.</p>
</description>
<pubDate>Fri, 22 Jul 2016 00:00:00 -0600</pubDate>
<link>http://www.pixio.com/blog/2016-07-22/wrap-battle-wrapping-c-with-swift-and-java/</link>
<guid isPermaLink="true">http://www.pixio.com/blog/2016-07-22/wrap-battle-wrapping-c-with-swift-and-java/</guid>
<category>c</category>
<category>swift</category>
<category>java</category>
<category>JNI</category>
<category>FFI</category>
<category>programming</category>
</item>
<item>
<title>C Considered Awesome</title>
<description><p><sup><sup>Everything written here is garbage and you should not listen to a word of it. Enjoy.</sup></sup></p>
<p>With so many languages, platforms, and frameworks in today&#39;s modern computer development world, it&#39;s easy to lose sight of the foundations of the field that have made computing great. Without question one of those pillars is the C programming language. C is <em>everywhere</em>, it&#39;s all around us, even now in this very room. You can see it when you look out your window (probably), or when you turn on your television (almost definitely). You use it when you go to work, when you go to church, when you pay your taxes. C underlies much of the computing done today whether you know it or not. And that&#39;s what makes it so important.</p>
<p>But beyond importance, it&#39;s a great language to work with. There are so many subtle features and tricks you can take advantage of that have been folded into the intricate, time-tested fabric of the C language (and its derivative languages). It&#39;s cool that you can write a website with 4 characters of ruby code or make make the next $1Trillion app by drag and dropping a zipped text file into a web service, but some engineering challenges really do <em>need</em> to be solved. And sometimes those problems are best solved with low-level, performant, close-to-the-metal, no-holds-barred, potentially-cryptic, always-awesome C code.</p>
<p>But let&#39;s talk about why you&#39;re here. You&#39;re here to learn some of those tricks that make C the greatest language around. I will warn you that if you use some of these in your own projects, your less-enlightened coworkers may begin to fear or despise your clear mastery of the art of the code. But soldier on. These tricks will almost definitely make your code the most memorable and unique works of typography at your firm. You may even begin to receive attention from upper management that could potentially have life-changing effects on your career.</p>
<p>Are you ready?</p>
<h2 id="c-tricks-your-instructor-never-told-you-about">C Tricks Your Instructor Never Told You About</h2>
<p>Think of these tricks as lifehacks for code. Once you know about them, you won&#39;t be able to help but sprinkle them around your code. And the impact of this will be hard to miss.</p>
<h3 id="c-supports-inline-citations-right-in-your-code">C supports inline citations right in your code</h3>
<p>Have you ever been stumped? Don&#39;t worry, it happens to everyone. But sometimes other people were stumped before you by the same problem. When they solved it, they posted their solutions for all to see. But you probably don&#39;t want to steal their implementation outright. If your boss found out, they might think you don&#39;t know how to do your job.</p>
<p>Let&#39;s turn the tables. After seeing this advanced knowledge in action, your boss will have no question of your skill and you get to use the code you found without fear.</p>
<p>Let&#39;s see it in action. Your boss asks you to fill out this method:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">void</span> <span class="nf">print_sevenTimes</span><span class="p">(</span><span class="kt">char</span><span class="o">*</span><span class="n">str</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">len</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Do your job here
</span><span class="p">}</span>
</code></pre></div>
<p>So you come up with a solution:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">void</span> <span class="nf">print_sevenTimes</span><span class="p">(</span><span class="kt">char</span><span class="o">*</span><span class="n">str</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">len</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// ensure null termination
</span> <span class="n">str</span><span class="p">[</span><span class="n">len</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span> <span class="c1">// 1
</span> <span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span> <span class="c1">// 2
</span> <span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span> <span class="c1">// 2
</span> <span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span> <span class="c1">// 4
</span> <span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span> <span class="c1">// 5
</span> <span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span> <span class="c1">// 6
</span> <span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span> <span class="c1">// 7
</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>But your boss comes back with a change from the client. They actually want to be able to specify how many times it prints. So your boss suggests that a loop might help. Now you&#39;ve got serious trouble. So you jump online and search for a loop. Here&#39;s an accepted answer that looks promising: <a href="http://stackoverflow.com/a/3477439">http://stackoverflow.com/a/3477439</a>.</p>
<p>Let&#39;s see the code that will impress your boss.</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">void</span> <span class="nf">printmanyTimes</span><span class="p">(</span><span class="kt">char</span><span class="o">*</span><span class="n">str</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">len</span><span class="p">,</span> <span class="kt">int</span> <span class="n">times</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// ensure null termination
</span> <span class="n">str</span><span class="p">[</span><span class="n">len</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">jmp_buf</span> <span class="n">buf</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span> <span class="n">setjmp</span><span class="p">(</span><span class="n">buf</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">times</span> <span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">str</span><span class="p">);</span> <span class="c1">// 7
</span> <span class="n">longjmp</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="n">i</span><span class="o">++</span><span class="p">);</span>
<span class="p">}</span>
<span class="nl">http:</span><span class="c1">//stackoverflow.com/a/3477439
</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>Notice how the power of C let&#39;s you paste your link right into your function so you can document the source of the loop code you&#39;re using. That&#39;s some forward thinking on the part of the language designers.</p>
<p>Now your code can print as many times as your boss wants and if anyone asks how it works, you can kindly direct them to line 12. No plagiarism, no problems #tripleairhorn.</p>
<h3 id="the-loop-anyone-can-read">The Loop Anyone Can Read</h3>
<p>So your clients just dropped another head scratcher on your desk. You&#39;ve got to double the contents of an entire array:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">void</span> <span class="nf">doubleMyArray</span><span class="p">(</span><span class="kt">int</span> <span class="o">*</span> <span class="n">arr</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">len</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// double every element
</span><span class="p">}</span>
</code></pre></div>
<p>After a bit of trial and error, you&#39;ve concluded that normal multiplication isn&#39;t what you&#39;re after, then you remember the printing problem. Aha! This calls for a loop. But hold on there, we don&#39;t want to just copy-paste the loop we found before. That&#39;s old hat. And some of your coworkers wanted you to teach them how it worked. No one has time for distractions like that. Time for a new trick.</p>
<p>You already know about <code>while</code> but you&#39;re wishing it were simpler. Think about all those times you forgot to mess with the condition variable and all the wasted hours waiting in vain for your program to finish. Let me introduce you to the only <code>while</code> you&#39;ll ever use: the down-to-while.</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">void</span> <span class="nf">doubleMyArray</span><span class="p">(</span><span class="kt">int</span> <span class="o">*</span> <span class="n">arr</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">len</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// double every element
</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">len</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span> <span class="n">i</span> <span class="o">--&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// while i goes down to 0, brilliant!
</span> <span class="n">arr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">*=</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// done, baby
</span> <span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>The designers of the C language understood the complex nature of looping control flow (loop code, for short). That&#39;s why they included an operator just for loops that makes it clear to anyone what&#39;s going on. The down-to operator <code>--&gt;</code> is handy because it&#39;s totally clear what&#39;s going on. Now the next time your coworkers ask for an explanation, you can laugh and say &quot;While <code>i</code> goes down to 0. Duh.&quot;.</p>
<h3 id="arrays-aren-39-t-picky">Arrays Aren&#39;t Picky</h3>
<p>You see arrays a lot in code. I think I use them almost every time I write a code. And I bet, like me, you&#39;ve been confused when someone gives you an <code>int *</code> and tells you it&#39;s &quot;just an array&quot;. Yeah? Then where&#39;s the <code>[]</code>, huh buddy? Fear not. They&#39;re actually not wrong, despite how confusing it might seem. But when dealing with these arrays-in-pointers clothing, it might be easy to get confused. Normally in code like this, it&#39;s easy to get something out of an array:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">int</span> <span class="n">myArr</span><span class="p">[];</span>
<span class="n">myArr</span><span class="p">[</span><span class="mi">5</span><span class="p">];</span>
</code></pre></div>
<p>It&#39;s clear from the declaration that the way you access the array is with the <code>[]</code>. You can even copy the whole shebang and just fill in the <code>[]</code> part. But does the same hold true for these <code>int*</code> things?</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">int</span> <span class="o">*</span><span class="n">myArr2</span><span class="p">;</span>
<span class="o">*</span><span class="n">myArr25</span><span class="p">;</span> <span class="c1">// ?
</span><span class="mi">5</span><span class="o">*</span><span class="n">myArr2</span><span class="p">;</span> <span class="c1">// ?
</span><span class="o">*</span><span class="mi">5</span><span class="n">myArr2</span><span class="p">;</span> <span class="c1">// ?
</span><span class="mi">5</span><span class="o">*</span><span class="mi">5</span><span class="n">myArr2</span><span class="p">;</span> <span class="c1">// ????
</span></code></pre></div>
<p>There&#39;s got to be a better way. And there is. It turns out, you can actually use (as you may have noticed in some of the code for previous tricks) the <code>[]</code> just the same. But without the copy-paste opportunity, it may be difficult to remember exactly what to do. Never fear. Once again, the C people saw this one coming. That&#39;s why the <code>[]</code> is so flexible. What do I mean? Let me show you:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="kt">int</span> <span class="o">*</span> <span class="n">myArr3</span><span class="p">;</span>
<span class="n">myArr3</span><span class="p">[</span><span class="mi">5</span><span class="p">];</span> <span class="c1">// 👍
</span><span class="mi">5</span><span class="p">[</span><span class="n">myArr3</span><span class="p">];</span> <span class="c1">// also 👍
</span></code></pre></div>
<p>You don&#39;t even need to worry about where to put those brackets. As long as you remember that they separate the first and second parts (they go around the second part), you&#39;re good. C&#39;s got you covered. Never fear the pointer again.</p>
<h3 id="getting-internal-with-extern">Getting Internal With Extern</h3>
<p>There are times where, despite your best effort, you need code that is not your own. We&#39;ve seen this already. Sometimes, though, it&#39;s not code you have access to directly. Let&#39;s look at a mock real world example.</p>
<p>You&#39;ve got a library that your company is licensing for a ton of money. The eggheads behind this baby are something else. In this library (you know this because you go drinking with a guy who use to work at the company that makes it) there&#39;s a special number they use that makes a ton of their calculations faster. Now, everyone knows that this is the secret sauce of this company and you&#39;ve got to pay them to taste it. Every time you call any codes that use this number, their library records it and it goes on your monthly licensing bill. But your boss thinks <em>you</em> can do better. And he&#39;s right.</p>
<p>This is where <code>extern</code> comes in. You may have seen this keyword used already to let you give others access to your code from a header file while keeping the implementation safely away from prying eyes in your .c file (or better yet, a .dll). But <code>extern</code> has another use. It can actually be used to pull things directly into your code from elsewhere. Let&#39;s take a look:</p>
<div class="highlight"><pre><code class="language-c" data-lang="c"><span class="c1">// Code.c
</span><span class="cp">#include &lt;expensiveLib.h&gt;
</span>
<span class="c1">// let's grab their magic constant.
// Your friend let you know the variable they store it in is called finvsqc (wtf lol?)
</span><span class="k">extern</span> <span class="kt">int</span> <span class="n">finvsqc</span><span class="p">;</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%d</span><span class="se">\r\n</span><span class="s">"</span><span class="p">,</span> <span class="n">finvsqc</span><span class="p">);</span> <span class="c1">// 1597463007 (what's so special about this number?) Oh well
</span><span class="p">}</span>
</code></pre></div>
<p>Even though the clever folks at the library company didn&#39;t put any mention of <code>finvsqc</code> in any of their header files, you can still reach right in and grab it if you know the name. You&#39;ve just saved your company money and made your boss look like a hero to the CFO. Nice job.</p>
<h1 id="objective-c-structure-beyond-structs">Objective-C: Structure Beyond Structs</h1>
<p>Long ago in the history of computing, the idea of Objects was invented. Data storage with specialized methods defined on them. And with objects came inheritance: the ability to make more complex versions of an object or change its behavior by creating a modified version that inherited from the original. It wasn&#39;t long after that these ideas were brought to C at the language level. Although, not C itself. Like the concept of objects, languages were designed that inherited from C and added functionality (like Objects). Two notable examples of this are C++ and Objective-C. </p>
<h2 id="the-runtime-won-39-t-even-see-you-coming">The Runtime Won&#39;t Even See You Coming</h2>
<p>Although Objective-C was invented later than C++, I&#39;ll be going over my Objective-C tricks first. These will be shorter than the C tricks because you may be unfamiliar with these languages so there&#39;s no need to add the confusion of a story problem.</p>
<h3 id="context-is-everything">Context Is Everything</h3>
<p>Think of this trick as a conceptual bridge between the C tricks above and Objective-C. The trick itself applies to C just as well, but really shines in Objective-C. You&#39;ll see what I mean.</p>
<p>In Objective-C and more specifically, the Foundation libraries provided by Apple, there are a host of methods which take a &quot;context&quot; argument to help you keep multiple calls and callbacks straight. A call to one of these might look like this:</p>
<div class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="p">[</span><span class="n">foo</span> <span class="nf">addObserver</span><span class="p">:</span><span class="n">self</span> <span class="nf">forKeyPath</span><span class="p">:</span><span class="s">@"bar"</span> <span class="n">options</span><span class="o">:</span><span class="mi">0</span> <span class="n">context</span><span class="o">:</span><span class="p">...];</span>
</code></pre></div>
<p>Don&#39;t mind the brackets, that&#39;s just the way object methods are called. The Objective-C designers opted for this type of method call because it makes the code read like english and is therefore &quot;self-documenting&quot;. Neat.</p>
<p>In the snippet above you can see we left the <code>context</code> argument blank. Well, you have to specify something. According to Apple, <code>context</code> is:</p>
<blockquote>
<p>Arbitrary data that is passed to <code>anObserver</code> in <code>observeValueForKeyPath:ofObject:change:context:</code>.</p>
</blockquote>
<p>So what do we use if our use case has no context, or is context-free if you will. The designers of Objective-C knew you&#39;d ask that and they have the perfect context for you to use in this case: <code>free</code>. You can just go ahead and type <code>free</code> so Objective-C knows you don&#39;t want to use a context:</p>
<div class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="p">[</span><span class="n">foo</span> <span class="nf">addObserver</span><span class="p">:</span><span class="n">self</span> <span class="nf">forKeyPath</span><span class="p">:</span><span class="s">@"bar"</span> <span class="n">options</span><span class="o">:</span><span class="mi">0</span> <span class="n">context</span><span class="o">:</span><span class="n">free</span><span class="p">];</span>
</code></pre></div>
<p>How&#39;s that for self documenting? Anyone who is reading this code will instantly know that you don&#39;t care about the context in this case and your observing is context-free.</p>
<h3 id="can-i-see-your-id">Can I See Your ID</h3>
<p>In Objective-C, all objects inherit from <code>NSObject</code>. So if you want to define a function that takes in an object, it works like this:</p>
<div class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="n">BOOL</span> <span class="nf">isObject</span><span class="p">(</span><span class="n">NSObject</span><span class="o">*</span> <span class="n">object</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">object</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>Alternatively, the language adds a new keyword <code>id</code> which just means object. So you can transform the above function into:</p>
<div class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="n">BOOL</span> <span class="nf">isObject</span><span class="p">(</span><span class="n">id</span> <span class="n">object</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">object</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>Check that out. Think of the keystroke savings, and as a bonus you don&#39;t even have to worry about the <code>*</code> at all. But the true benefits are yet to come. Let&#39;s say I have this class:</p>
<div class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="k">@interface</span> <span class="nc">NumberTracker</span> <span class="p">:</span> <span class="nc">NSObject</span>
<span class="k">@property</span> <span class="p">(</span><span class="n">nonatomic</span><span class="p">)</span> <span class="n">id</span> <span class="n">delegate</span><span class="p">;</span>
<span class="k">@property</span> <span class="p">(</span><span class="n">nonatomic</span><span class="p">)</span> <span class="n">NSNumber</span><span class="o">*</span> <span class="n">trackedNumber</span><span class="p">;</span>
<span class="k">@end</span>
</code></pre></div>
<p>It&#39;s great for tracking numbers, but as you may have heard, computers don&#39;t understand money numbers. Well, not normally. The authors of the Foundation library understood this and created a class that could help us out: <code>NSDecimalNumber</code>. It&#39;s like <code>NSNumber</code> but for decimal number systems like currency. Let&#39;s use it to make our money tracker:</p>
<div class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="k">@interface</span> <span class="nc">MoneyTracker</span> <span class="p">:</span> <span class="nc">NumberTracker</span>
<span class="k">@property</span> <span class="p">(</span><span class="n">nonatomic</span><span class="p">)</span> <span class="n">id</span> <span class="n">delegate</span><span class="p">;</span>
<span class="k">@property</span> <span class="p">(</span><span class="n">nonatomic</span><span class="p">)</span> <span class="n">NSDecimalNumber</span><span class="o">*</span> <span class="n">trackedMoney</span><span class="p">;</span>
<span class="k">@end</span>
</code></pre></div>
<p>But in the implementation, we want to have the <code>trackedMoney</code> property use the same storage as the old <code>trackedNumber</code> to save memory. If we did this, the compiler would complain:</p>
<div class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="k">@implementation</span> <span class="nc">MoneyTracker</span>
<span class="k">-</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="n">init</span> <span class="p">{</span>
<span class="n">self</span> <span class="o">=</span> <span class="p">[</span><span class="n">super</span> <span class="nf">init</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">)</span> <span class="p">{</span>
<span class="n">_trackedNumber</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSDecimalNumber</span> <span class="nf">alloc</span><span class="p">]</span> <span class="nf">init</span><span class="p">];</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">self</span><span class="p">;</span>
<span class="p">}</span>
<span class="o">-</span> <span class="p">(</span><span class="n">NSDecimalNumber</span><span class="o">*</span><span class="p">)</span><span class="n">trackedMoney</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">[</span><span class="n">self</span> <span class="nf">trackedNumber</span><span class="p">];</span> <span class="c1">// compiler warning
</span><span class="p">}</span>
<span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">setTrackedMoney</span><span class="o">:</span><span class="p">(</span><span class="n">NSDecimalNumber</span><span class="o">*</span><span class="p">)</span><span class="n">trackedMoney</span> <span class="p">{</span>
<span class="p">[</span><span class="n">self</span> <span class="nf">setTrackedNumber</span><span class="p">:</span><span class="n">trackedMoney</span><span class="p">];</span>
<span class="p">}</span>
<span class="k">@end</span>
</code></pre></div>
<p>But we <em>know</em> that it&#39;s an <code>NSDecimalNumber</code>. Fortunately you can use the handy <code>id</code> keyword to tell the compiler that you know what you&#39;re doing:</p>
<div class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="k">-</span> <span class="p">(</span><span class="n">NSDecimalNumber</span><span class="o">*</span><span class="p">)</span><span class="n">trackedMoney</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="n">id</span><span class="p">)[</span><span class="n">self</span> <span class="nf">trackedNumber</span><span class="p">];</span> <span class="c1">// take a step back, compiler, I got this
</span><span class="p">}</span>
</code></pre></div>
<p>It&#39;s that simple and you&#39;ve eliminated another warning.</p>
<h1 id="c-the-evolution">C++: The Evolution</h1>
<p>C++ is an entirely different animal than C. It looks like C at first glance but you&#39;ll start to notice lots of <code>&lt;&gt;</code> and <code>&lt;&lt;</code> and <code>::</code>. C++ is C on another level (hence the name). It adds objects and classes and a whole host of other things that make it a wonderful, powerful successor to the ubiquitous C for those brave enough to undertake learning it. Since we looked at subclassing in the Objective-C tricks section, I thought it was worth mentioning the <em>even more powerful</em> subclassing you can do in C++. This is the only C++ trick I&#39;ll be offering today, but it should get you on the right road if you&#39;re just starting of in C++ development.</p>
<h2 id="a-taste-of-change">A Taste of Change</h2>
<p>C++ takes object orientedness to an entirely new level by allowing your classes to inherit from <em>multiple</em> parent classes. That&#39;s right. You can inherit the functionality and member variables of more than once class at a time. Let&#39;s take a dive into how this works.</p>
<p>Your boss comes to you with a new color receipt printer and an SDK for it. The SDK method you have to call is:</p>
<div class="highlight"><pre><code class="language-c++" data-lang="c++"><span class="kt">void</span> <span class="n">printColoredString</span><span class="p">(</span><span class="n">PrinterString</span> <span class="n">str</span><span class="p">,</span> <span class="n">PrinterColor</span> <span class="n">clr</span><span class="p">)</span>
</code></pre></div>
<p>But you already have code to run the old SDK for the black and white printers that takes just a string:</p>
<div class="highlight"><pre><code class="language-c++" data-lang="c++"><span class="kt">void</span> <span class="n">printString</span><span class="p">(</span><span class="n">PrinterString</span> <span class="n">str</span><span class="p">);</span>
</code></pre></div>
<p>Rather than add another list of colors that you have to keep consistent with your existing string list, bask in the glory of the C++ designers&#39; wisdom and leverage multiple inheritance. You simply need to create a drop-in replacement for <code>string</code> that you can use in <em>both</em> SDK versions. But what would that look like? Like this:</p>
<div class="highlight"><pre><code class="language-c++" data-lang="c++"><span class="k">class</span> <span class="nc">PrintableString</span> <span class="o">:</span> <span class="k">public</span> <span class="n">PrinterString</span><span class="p">,</span> <span class="k">public</span> <span class="n">PrinterColor</span> <span class="p">{</span>
<span class="c1">// everything is already implemented by the individual classes. C++ WIN!
</span><span class="p">};</span>
</code></pre></div>
<p>Now that you have that all set, you only have to make a minor modification to the way you use the SDK:</p>
<div class="highlight"><pre><code class="language-c++" data-lang="c++"><span class="kt">void</span> <span class="nf">internal_stringPrint</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">PrintableString</span><span class="o">&gt;</span> <span class="n">strings</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">strings</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">printsdk</span><span class="o">::</span><span class="n">printsdk</span><span class="p">.</span><span class="n">version</span> <span class="o">&gt;</span> <span class="mf">2.0</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// new code
</span> <span class="n">printsdk</span><span class="o">::</span> <span class="n">printColoredString</span><span class="p">(</span><span class="n">strings</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">strings</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="c1">// old code
</span> <span class="n">printsdk</span><span class="o">::</span><span class="n">printString</span><span class="p">(</span><span class="n">strings</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>That conversion is so simple. And if any functionality gets added, you can just add to <code>PrintableString</code> and add another case to <code>internal_stringPrint</code>. C++ is powerful.</p>
<h1 id="c-you-later">C You Later</h1>
<p>Now that you&#39;ve gotten a taste of the things that make C (and its descendants) so great, I hope you&#39;re filled with the same passionate feelings that this code inspires in anyone who encounters it. Thanks for reading all the way to then end.</p>
<p><center>
<img src="/img/posts/thumbs-up.jpg" alt="success">
</center></p>
<style>
img {
max-width: 500px;
display: inline-block;
}
</style>
</description>
<pubDate>Fri, 15 Jul 2016 00:00:00 -0600</pubDate>
<link>http://www.pixio.com/blog/2016-07-15/c-considered-awesome/</link>
<guid isPermaLink="true">http://www.pixio.com/blog/2016-07-15/c-considered-awesome/</guid>
<category>c</category>
<category>c++</category>
<category>objective-c</category>
<category>best practices</category>
<category>coding</category>
<category>awesome</category>
<category>success</category>
<category>seo</category>
<category>tags</category>
<category>low level</category>
<category>software</category>
<category>hardware</category>
<category>computer</category>
<category>thoughts</category>
<category>ideas</category>
<category>good</category>
<category>great</category>
<category>programming</category>
</item>
<item>
<title>How to score big with Android's NDK</title>
<description><p>We have an unhealthy love for Rocket League here at Pixio, but our games usually end up looking like this:</p>
<p><center>
<img src="/img/posts/ndk/cat-rocket-league.gif" alt="Cat Picture">
</center></p>
<p>This is exactly what most people feel like when they first dive into the <a href="https://developer.android.com/ndk/index.html">Android Native Deveolpment Kit (NDK)</a>. At I/O 2015 Google announced better support for the Android NDK and these improvements have made native development easier than ever before. Let&#39;s go through some quick examples to see how to set up your code to take advantage of the new NDK support provided by Android Studio.</p>
<h2 id="quick-background">Quick Background</h2>
<p>The Android NDK is a set of tools that let you use C and C++ code in your Android application. It uses the <a href="https://en.wikipedia.org/wiki/Java_Native_Interface">Java Native Interface (JNI)</a> which allows Java code interop with C/C++ code. While most projects will be better suited to only use Java, some projects such as games, physics simulators, or anything that requires lots of CPU could benefit from using the NDK. Additionally, applications which use shared C/C++ libraries will benefit.</p>
<h2 id="the-changes">The Changes</h2>
<p>Google made big changes when the switch from Eclipse to the current IntelliJ backed Android Studio. It brought improved features and a better environment to develop Android applications. With the <a href="https://plus.google.com/+jetbrains/posts/P61rd5DnNK2">announcement</a> at I/O 2015, Google integrated <a href="https://www.jetbrains.com/clion/">CLion</a>, the Jetbrains C/C++ IDE, into Android Studio to provide much better support for NDK development. This change brought things like code completion, refactoring, debugging, and many other features to make developing with C and C++ in Android applications much easier. This year they continued to add on to this new experience by adding the ability to support pre-existing NDK projects that used ndk-build or CMake rather than Gradle. Also, the new updates allows the programmer to use a single debugger for both the Java and C/C++ code in a project, streamlining the debugging process.</p>
<h2 id="setup">Setup</h2>
<p>We&#39;re going to use some of the most up to date tools to gain the most benefit out of the recent changes to the Android NDK. Currently the enhanced NDK support is not in the stable channel, so we will be using the 2.2 preview 4 version of Android Studio and the 0.7.2 version of the Experimental Gradle plugin.</p>
<h3 id="android-studio">Android Studio</h3>
<p>First let&#39;s download and setup Android Studio. Since we are using a Canary version of Android Studio, Google recommends installing it alongside your stable version of Android Studio instead of replacing it. You can find the download <a href="http://tools.android.com/download/studio/builds/2-2-preview-4">here</a>.</p>
<h3 id="create-android-project">Create Android Project</h3>
<p>Now that we have Android Studio setup and running, lets create a new project for our example. Let&#39;s call our project <code>Android NDK Example</code>.</p>
<p><img src="/img/posts/ndk/new1.png" alt="New Android Project">
<img src="/img/posts/ndk/new2.png" alt="New Android Project">
<img src="/img/posts/ndk/new3.png" alt="New Android Project">
<img src="/img/posts/ndk/new4.png" alt="New Android Project"></p>
<h3 id="install-ndk-package">Install NDK Package</h3>
<p>Before we can write any code we need to install and configure the NDK. Open the SDK Manager and browse to the SDK Tools tab. Find the NDK and check the box next to it. Hit apply or OK to start the download. </p>
<p><img src="/img/posts/ndk/sdk-ndk.png" alt="NDK install example"></p>
<p>Installing the NDK can take a long time. It is a large download (&gt;1GB) so make sure you have a fast connection. While you&#39;re waiting read a book, take a nap, or go play some Rocket League (my personal choice).</p>
<p>Once the NDK package has been installed, we need to make sure our project knows where to find it. Ensure that your project structure points to the correct NDK package.</p>
<p><img src="/img/posts/ndk/ndklocation.png" alt="NDK install location"></p>
<h3 id="configure-project">Configure Project</h3>
<p>Now that we have our project created and the NDK Package configured, let&#39;s get our project ready for some native code. First let&#39;s edit the project gradle file. We need to tell it we are going to use the experimental gradle plugin. Let&#39;s change the classpath line for gradle to say this:</p>
<div class="highlight"><pre><code class="language-" data-lang="">classpath 'com.android.tools.build:gradle-experimental:0.7.2'
</code></pre></div>
<p>Next let&#39;s edit the app module gradle file. The DSL has changed with the experimental gradle plugin so we need to update our app&#39;s gradle.</p>