Visual Studio 2015 Preview – Mobile C++

C++ has long been a great option for cross-platform mobile development particularly in the cases where you might have an existing C++ codebase or you have certain types of performance considerations. For this article I am going to constrain the subject to mobile platforms; iOS, Android and Windows but of course this could extend to any OS with C++ support. So let’s start by taking a look at the C++ support for each.

Android

Android provides an NDK (Native Development Kit) (see https://developer.android.com/tools/sdk/ndk/index.html) for use when working with C++. The NDK includes a set of cross-toolchains (compilers, linkers, etc.) that can generate native ARM binaries on Linux, OS X, and Windows (with Cygwin) platforms. The Java Native interface (JNI) provides a way to interface native code with Java (more info on that here http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html). You can use the NDK to write C++ code and you can either use the JNI to interface this code with a Java Android app or you can write a NativeActivity which provides the interface to application lifecycle events for your convenience. For my example I will use the JNI approach and I will create the project using Android Studio.After creating a new Blank Activity app I had to set up a few things:

Now placing C++ code into src > main > jni will compile it into a library, in this case libHello.so

The code I used I modified the hellojni sample from he NDK.

Notice the function naming convention used. (You can generate this header using javac and javah command lines). The code to consume this from the Java activity is pretty straight-forward:

To test this I used the new Visual Studio Android emulator from Android Studio. If the emulator is already running when you start debugging from Android Studio the emulator will appear as a running device debugging target.

And here’s the final result:

iOS

Looks like this is easier in iOS if you are writing an Objective-C app since you can mix and match C++ and use it directly. You can’t do this with Swift directly; for that you would need an Objective-C wrapper. The Default compiler for C/C++/Objective-C in XCode 6.2 is set as Apple LLVM 6.0 for which the front-end compiler is Clang

As an example, I tried to write a C++ class, within a dynamic shared library, and consume it from an Objective-C app:

The NativeTest project shown above is an Objective-C iOS app in which I added a Label control to the ViewController. This app references the other project, which is a Framework encapsulating a dynamic shared library which contains a class called MyClass which, in turn, exposes a method which returns a string which I use to set the text of the Label in the UI. That’s about as simple as you can get but still illustrate how the C++ code can be used.

This shows the result running in the iOS simulator on my Mac:

Windows

You can create a fully native Universal app in C++ which includes a XAML layer for the user interface or you can mix and match by wrapping your C++ as a WinRT component which could then be consumed from within a .NET or Javascript app. I’m not going to cover a WinRT component here since for this post I intend to use the former method; a C++ XAML Windows Phone app. In fact, there is no need to show how this is done since the UI code is also written in C++ so, any additional C++ can be written in place. On Windows the visual C++ compiler is used.

Unified Solution

At this point there is no direct support for creating an iOS native library so let’s put together a solution containing Android and Windows Phone and then speculate about what might be possible moving forwards. So the idea would be to have an architecture which looks a bit like the following:

I won’t bother with the Platform Abstraction layers for my simple example but it’s not easy to see why these would be created in a real project. Herb also links to some online talks which detail projects (Office and Dropbox) which have employed C++ heavily in their cross-platform strategy.

The main concept here is to write as much of the code as standards-compliant C++ which can be shared by each platform. Following an MVVM (Model View ViewModel) approach fits quite nicely here as the platform-specific layer at the top would consist purely of user interface code and a binding layer and ideally the View Models would sit inside the C++ bit and be shared.

I have worked on similar cross-platform code bases in the past but they have always involved retrieving the raw C++ files to each platform and building them within the environment that exists there. Bringing this within one tool would ease the burden of this workload.

Dynamic Shared Library

I started out by adding two apps to my solution; and Android c# app (Xamarin) and a Windows Phone C++ Xaml application. I then added one of the new templates in Visual Studio 2015, a Cross-Platform Dynamic Shared Library.

My solution now looks like this:

Note that within the SharedObject folder there are three projects; two for the platform specific code and the other where code can be added which can be shared. Each platform specific project is built separately and has it’s own output. The Android library project is built using the LLVM compiler toolchain and the Windows Phone library project is built using the visual C++ toolchain.

Effectively, the code in the shared project will get included into each platform specific project at compile time unless a file of that name already exists there. This provides another way, alongside using #ifdef platform defines of overriding shared code. Another nice IDE feature is that in the code editor you can access a drop-down which allows you to toggle the current build context, i.e. android or windows, in this case.

The result of toggling is that code irrelevant to the ‘current’ context is greyed out and error/warning squiggles are coloured appropriately to allow you to understand in which contexts they exist.

So now we have all of the required projects how do we reference the shared libraries from the app projects?

Android Shared Library

The output of the Android Shared Library uses the Unix shared library naming conventions and so is prefixed with ‘lib’ and the file extension is ‘.so’. I used the Add reference dialog fro the Android app project to add a project reference to the Android shared library. Then I used DllImport to reference a function inside the shared library like this:

Where the function in the shared library is declared in SharedObject.h like this

extern"C"constchar*GetTemplateInfo2();

and implemented in SharedObject.cpp like this:

#include"SharedObject.h"

constchar*GetTemplateInfo2()

{

#ifdef__ANDROID__

return"Hello from Android C++!";

#else

return"Hello from Windows C++!";

#endif

}

I could have provided different SharedObject.cpp files in each platform-specific project but in this case I was lazy and just used the pre-processor. Calling the imported function from the Android MainActivity like this

button.Click +=delegate { button.Text = GetTemplateInfo2(); };

works as expected in the new Visual Studio Android Emulator.

Note, if you get an error ‘DWP Handshake failed’ problem when deploying Android app from Visual Studio – I fixed this by switching off Use Fast Deployment

Windows Shared Library

The output here is a dynamic link library with ‘.dll’ extension and similar to the Android project I added a project reference to this from the Windows C++ XAML app. Examining the output dll file shows that by default no functions are exported (I used dumpbin.exe /exports – another alternative is to use dependency walker).

I fixed this by adding a .def file to the project and configuring the project to use it. Here are the contents of the .def file:

LIBRARY SharedObject.Windows

EXPORTS

GetTemplateInfo2

Building and running dumpbin again produces:

Notice the ‘GetTemplateInfo2’ function which, as it is declared extern “C” in the header doesn’t have it’s name in the mangled form that a C++ compiler would use. Ok, so now I can add a project reference from the C++ app to the shared project and since everything is native I can just reference the C++ header and lib file and call the exported function directly. However, I tried this and couldn’t get it to work like this so instead of calling the function like this:

constchar*str=GetTemplateInfo2();

I resorted to this:

constchar*GetText()

{

automod=LoadPackagedLibrary(L"SharedObject.Windows.dll",0);

if(mod==nullptr)

{

autoerr=GetLastError();

}

else

{

autoproc=(GetStringFnType)GetProcAddress(mod,"GetTemplateInfo2");

if(proc!=nullptr)

{

autoresult=proc();

returnresult;

}

FreeLibrary(mod);

}

return"";

}

and the result running in the Windows Phone emulator:

iOS

So what about iOS? Well, I spent a while thinking about what it might look like to add iOS into the mix and I came up with two different scenarios:

The LLVM tool chain used in an iOS build is ported to Windows and used to cross-compile binaries as required for an iOS shared library (.dylib). I believe the UI side of things is closed source so a Mac would still be required but the dylib could be built on Windows and copied over.

The build happens on a Mac and Visual Studio communicated back and forth to orchestrate the build.

Either way there is a great advantage in having an IDE that understands this scenario and can provide tooling to make the job easier.

Feedback

Remember, these tools are an early preview and as a result a bit rough around the edges – I’m sure the team building this out would appreciate your feedback. If you are trying out these features in Visual Studio 2015 Preview please provide feedback as follows:

– Visual Studio Feedback via the smile/frown in the VS menu at the top for quick suggestions/bugs

am new to programming. am trying to perfect c++, and later c#. my fear is that somewhere on the internet, I read that java is more powerful and better than c++, especially on web and mobile applications / games. also am more interested on windows phone / windows applications, which is while I also like to master c#

I prefer to be a master of one, than a jack of all trade, I will prefer to master c++ and c#(which I know is specifically for Microsoft), which I reckon are a little bit related

can you advice me. do I need to worry about learning java too, which might take up my time, I should be using in mastering and building stuff on c++/c#,

Hi Evan,
I would start with C# or Java which are fairly similar – make this choice dependent on your development environment and where you want your programs to run. C++ can be much more complex if you try to learn the whole thing. In your case, if you are interested in general-purpose, windows development then choose C#. Bear in mind also that .NET will be available on other platforms moving forwards and has been for a while with Mono.
Saying a language is more powerful than another doesn’t make sense without context – choice of languages would mostly boil down to which is better for a certain scenario – there will always be pros and cons.
Hope that helps,