45

I'm moving away from strict Android development and wanting to create iPhone applications. My understanding is that I can code the backend of iOS applications in C/C++ and also that I can use the NDK to include C/C++ code in Android apps. My question however is how? I've googled quite a bit and I can't find any clear and concise answers. When looking at sample code for the NDK, it seems that all the function names etc. are Android (or at least Java) specific and so I would not be able to use this C/C++ backend to develop an iPhone frontend? I'd appreciate some clarification on this issue and if at all available some code to help me out? (even just a simple Hello World that reads a string from a C/C++ file and displays it in an iOS and Android app).

Thanks guys Chris

Sonoman
  • 3,379
  • 9
  • 45
  • 61
  • 1
    The NDK is not for creating cross platform apps. It's for writing time-sensitive code in a native language – Falmarri Sep 08 '10 at 07:36
  • 1
    I see. Thanks for the answer. Could you advise on how to go about writing cross platform code (e.g. to share algorithms etc.)? – Sonoman Sep 08 '10 at 08:09
  • @Falmarri: From the NDK docs at http://developer.android.com/sdk/ndk/index.html "This can provide benefits to certain classes of applications, in the form of reuse of existing code". – Roddy Sep 20 '10 at 19:26
  • 3
    @Falmarri: regardless of Google's stated purpose with the NDK, if it "isn't for" creating cross-platform apps, then how do you suggest developers accomplish that? Porting code from Java to Objective C when you could write it once for both platforms in C++ is a waste of time. Granted, you can't do any front-end stuff like UI with the NDK (unless you're using OpenGL), but writing all your back-end logic in C++ and just building a separate UI will still save time. – Mitch Lindgren May 12 '11 at 23:29
  • See also http://stackoverflow.com/questions/3996793/game-engine-for-iphone-android/ – David d C e Freitas Aug 12 '11 at 07:37

6 Answers6

69

Note that I almost exclusively work on "business/utility/productivity" applications; things that rely heavily on fairly standard UI elements and expect to integrate well with their platform. This answer reflects that. See Mitch Lindgren's comment to Shaggy Frog's answer for good comments for game developers, who have a completely different situation.

I believe @Shaggy Frog is incorrect here. If you have effective, tested code in C++, there is no reason not to share it between Android and iPhone, and I've worked on projects that do just that and it can be very successful. There are dangers that should be avoided, however.

Most critically, be careful of "lowest common denominator." Self-contained, algorithmic code, shares very well. Complex frameworks that manage threads, talk on the network, or otherwise interact with the OS are more challenging to do in a way that doesn't force you to break the paradigms of the platform and shoot for the LCD that works equally badly on all platforms. In particular, I recommend writing your networking code using the platform's frameworks. This often requires a "sandwich" approach where the top layer is platform-specific and the very bottom layer is platform-specific, and the middle is portable. This is a very good thing if designed carefully.

Thread management and timers should also be done using the platform's frameworks. In particular, Java uses threads heavily, while iOS typically relies on its runloop to avoid threads. When iOS does use threads, GCD is strongly preferred. Again, the solution here is to isolate the truly portable algorithms, and let platform-specific code manage how it gets called.

If you have a complex, existing framework that is heavily threaded and has a lot of network or UI code spread throughout it, then sharing it may be difficult, but my recommendation still would be to look for ways to refactor it rather than rewrite it.

As an iOS and Mac developer who works extensively with cross-platform code shared on Linux, Windows and Android, I can say that Android is by far the most annoying of the platforms to share with (Windows used to hold this distinction, but Android blew it away). Android has had the most cases where it is not wise to share code. But there are still many opportunities for code reuse and they should be pursued.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Hi, Rob, in your answer you recommend writing networking code natively, I'd like to know what library to use to write the networking code. `cURL`? Or if I want to use plain socket, is it possible to share the socket related code between Android and iOS? – neevek Oct 15 '12 at 07:59
  • 2
    I recommend native networking. You get better power management, integration with the certificate keychain, proxies, authentication system, and simpler code. NSURLConnection is much easier to deal with than cURL (having done a lot of cURL work). Android also has good native networking support. Low-level sockets are best handled on iOS with GCDAsyncSocket https://github.com/robbiehanson/CocoaAsyncSocket/wiki/Intro_GCDAsyncSocket. This is exactly the kind of code you shouldn't share. When you try, you wind up managing NTLM authentication by hand rather than getting it for free (true story). – Rob Napier Oct 15 '12 at 11:40
  • @RobNapier We have one App which use http web service call in android and as well in iphone.But now we want to write a common code for this http web service call in c/c++ then use that code in android and iphone.Can you point me where i should start. – Herry Mar 13 '13 at 09:12
  • 2
    If by web service, you mean SOAP, then that's a real pain on iOS, and I'd recommend REST instead. Easy to consume by both, and I do not recommend sharing the code. RESTKit or MKNetworkKit or the other REST toolkits for iOS are too good. Let all the networking be done natively, then just consume the data in shared C++ if that kind of code sharing is a real benefit to you (but integrating C++ into Android is a pain, so it had better be a major benefit). – Rob Napier Mar 13 '13 at 13:49
  • If you must use SOAP, then I recommend writing your handler in gsoap. That can be shared by both. – Rob Napier Mar 13 '13 at 13:49
  • `Android is by far the most annoying of the platforms to share with`. And so, almost 5 years later nothing has changed. It's still painful to work with NDK. – Dmitry Zaytsev Jan 06 '16 at 16:56
4

While the sentiment is sound (you are following the policy of Don't Repeat Yourself), it's only pragmatic if what you can share that code in an efficient manner. In this case, it's not really possible to have a "write once" approach to cross-platform development where the code for two platforms needs to be written in different languages (C/C++/Obj-C on iPhone, Java for Android).

You'll be better off writing two different codebases in this case (in two different languages). Word of advice: don't write your Java code like it's C++, or your C++ code like it's Java. I worked at a company a number of years ago who had a product they "ported" from Java to C++, and they didn't write the C++ code like it was C++, and it caused all sorts of problems, not to mention being hard to read.

Shaggy Frog
  • 27,575
  • 16
  • 91
  • 128
  • 1
    Thanks for the response! I was just hoping that I would be able to code a Viterbi or Baum Welch restimation algorithm in C++ and just access if from Android. It just seems such a shame to have to write something as time-critical (it's for a real-time application) not only in Java, but repeat the same algorithm twice. In any case, thanks for the advice. – Sonoman Sep 09 '10 at 07:08
  • 2
    Actually, time-critical/performance-critical components are exactly the kinds of things you *should* be writing natively for each device. (It sounds like you're writing code to implement a Hidden Markov Model) – Shaggy Frog Sep 09 '10 at 07:18
  • 1
    Correct :p I guess I was just trying to be lazy and save myself writing code twice. Obviously I'll be writing the code natively for the iPhone but it's just a bit of a pain to have to write code for each Android device I want to support rather than just be able to invoke code from the VM. If I was writing a game for instance, (which I am also doing) that implements GAs to control AI, it's also a bit of a pain to have to implement this twice, so this is why I was hoping for an easy solution. – Sonoman Sep 09 '10 at 08:13
  • 2
    Laziness is a good quality for a programmer (it's one of the Three Virtues), but you have to be pragmatic about when you apply it. Not wanting to write code twice is a good attitude. However, when that makes you jump through huge hoops because you're trying to write one set of code for two completely different languages, then the effort is not worth the gain. – Shaggy Frog Sep 09 '10 at 17:23
  • 14
    I downvoted this answer because I think it glosses over the benefits of the NDK. The only parts of an Android application that must be written in Java are the parts that use the Android libraries. If UI interactions and/or things like network communication comprise most of your codebase, then I'd agree that you're shooting yourself in the foot by using C++. But for games or apps that have only a thin UI layer over a backend which doesn't rely on platform-specific libraries, the NDK is absolutely the way to go. Rob provides a good overview of the pros and cons of the NDK in his answer. – Mitch Lindgren May 12 '11 at 23:35
2

Besides using C/C++ share so lib.

If to develop cross-platform apps like game, suggest use mono-based framework like Unity3D.

Else if to develop business apps which require native UI and want to share business logic code cross mobile platforms, I suggest use Lua embedded engine as client business logic center.

The client UI is still native and get best UI performance. i.e Java on Android and ObjectC on iOS etc. The logic is shared with same Lua scripts for all platform. So the Lua layer is similar as client services (compare to server side services).

-- Anderson Mao, 2013-03-28

Anderson Mao
  • 1,101
  • 1
  • 9
  • 7
2

Writing a shared code base is really practical in this situation. There is some overhead to setting up and keeping it organized, but the major benefits are these 1) reduce the amount of code by sharing common functionality 2) Sharing bug fixes to the common code base. I'm currently aware of two routes that I'm considering for a project - use the native c/c++ (gains in speed at the expense of losing garbage collection and setting targets per processor) or use monodroid/monotouch which provide c# bindings for each os's platform functionality (I'm uncertain of how mature this is.)

If I was writing a game using 3d I'd definitely use approach #1.

jchristof
  • 2,794
  • 7
  • 32
  • 47
2

I posted this same answer to a similar question but I think it's relevant so...

I use BatteryTech for my platform-abstraction stuff and my project structure looks like this:

On my PC:

  • gamename - contains just the common code

  • gamename-android - holds mostly BatteryTech's android-specific code and Android config, builders point to gamename project for common code

  • gamename-win32 - Just for building out to Windows, uses code from gamename project

On my Mac:

  • gamename - contains just the common code

  • gamename-ios - The iPhone/iPad build, imports common code

  • gamename-osx - The OSX native build. imports common code.

And I use SVN to share between my PC and Mac. My only real problems are when I add classes to the common codebase in Windows and then update on the mac to pull them down from SVN. XCode doesn't have a way to automatically add them to the project without scripts, so I have to pull them in manually each time, which is a pain but isn't the end of the world.

All of this stuff comes with BatteryTech so it's easy to figure out once you get it.

Sridhar Ratnakumar
  • 81,433
  • 63
  • 146
  • 187
rbgrn
  • 304
  • 2
  • 6
1

Though I don't use these myself as most of the stuff I write won't port well, I would recommend using something like Appcelerator or Red Foundry to build basic applications that can then be created natively on either platform. In these cases, you're not writing objective-c or java, you use some kind of intermediary. Note that if you move outside the box they've confined you to, you'll need to write your own code closer to the metal.

Scott
  • 16,711
  • 14
  • 75
  • 120