The Incredibly Great Revolutionary iPhone 5

After nearly one year with my Nokia Lumia 800, I decided to go over to the dark side; buy the new iPhone 5. Even though I liked the user interface on the Windows Phone platform, the phone was easy to use, there was still small details with the phone that did not make it fit for my use. Multitasking was not implemented good enough. Applications always had to start up from beginning when I tapped their shortcut or tile on the start screen. Even though the OS itself was fast and snappy, the 3rd party apps (some of Microsoft as well) had tons of bugs and had incredibly poor performance (Spotify and Facebook, just to mention a few). This made me switch over to the iPhone 5. I was already happy with the app support on my iPad, so I assumed I would get the same experience on my new iPhone.

Even though many consumers finds the iPhone 5 "The perfect phone", there is still room for improvements. iOS is a fast, smooth OS with a huge app store. Bugs are rarely seen and multitasking works perfectly. 

One thing that keeps annoying me is the amount of icons on the screen. Several times I have looked on my screen and I have to dive into a sea of icons in order to find the app I want to use. This is where the Windows Phone OS was far better at where there was large tiles that made it far easier to find apps. 

The user interface itself is quite old on iOS. It had not been through much change since the first iPhone release in 2007. The gray non customizable user-interface made it feel a bit like going back in time from Windows Phone to iOS. 

Spotify was perhaps the application I used most on my Windows Phone that was one entire nightmare. Even if it where able to play tracks, it was often slow at starting, crashed often and settings started resetting making my data-plan vanish in the beginning of the month. All the bugs on the app made it feel even worse than the beta release of Windows Vista on an old computer.

Im not a person who use my phone for games. In fact, my phone does not even have one single game installed. It is more a device I use to check out social networks, listen to music and read the news. Even if the iPhone got better app support and is better than the Windows Phone in some areas, there are still features I miss from the Windows Phone. 

Calling native code from C#

If you are like me, you like optimizing and profiling your code making it as fast as possible. However, at one point you might realize the C# language does not give you the best performance for whatever the purpose of your code is. Since C# is running in the Common Language Runtime (CLR), there is a larger overhead between what the machine is doing and what your code is doing. It is therefore necessary to go a language of lower level. In my case, I went to C++. C++ is compiled into assembly code when compiled, making it a low-level language. You can also go deeper if the C++ code does not give the desired performance. However, if the code you want to have in C++ contains just a few lines of code, it could in fact be a better way to keep it in C#.

This post will create a basic function returning the result of x to the power of n given that n is larger than or equal to 0. A normal C# function would this would be as follows: (I avoid using library functions to make my examples more clear)

 

public static void Main()
{
	Console.WriteLine("5^4 is {0}", Power(5, 4));
	Console.ReadKey();
}

private static int Power(int x, int n) { int value = 1; for (int i = 0; i < n; i++) value = value * x;

return value;

}

 

 

We want to move this code to C++.

First, I add a empty C++ project to my solution file in Visual Studio (DLL Win32 application). Now comes the ugly part. My source file in the C++ project would look like this:

 

#include <windows.h>

extern “C” __declspec(dllexport) int __stdcall Power(const int x, const int n);

BOOL __stdcall DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) { return TRUE; }

extern “C” __declspec(dllexport) int __stdcall Power(const int x, const int n) { int value = 1; for (int i = 0; i < n; i++) value = value * x;

return value;

}

 

The DllMain method just indicates where the main part of the DLL file is. It works a bit like a constructor in classes. All the "extern "C" __declspec(dllexport) int __stdcall" says it is a int function that is used outside the DLL file by other programs. 

In order to call my native C++ function, I would have to add more code to my C# project. 

[DllImport("NativePower.dll")]
private static extern int Power(int x, int n);

public static void Main() { Console.WriteLine(“5^4 is {0}”, Power(5, 4)); Console.ReadKey(); }

It is important to place the NativePower.dll file in the same folder as the debug folder for our C# application unless we want the application to die in a DllNotFoundException. 

This method of calling native code is called P/invoke (Patform invoke). It is often used by the .NET framework itself to call different methods to the Windows kernel or other system DLL files. It can technically be used by any DLL file coded in any programming language as long as the CLR manages to read the DLL file. I miss some debugging functionality in Visual Studio for importing DLL files since this function could be hard to debug. In some situations you might want to pass strings, arrays or pointers as an argument in the DLL file. It is then needed to use marshaling. Marshalling means you take a data type and its values and makes it compatible with another programming language by converting it. 

 

Description

Windows Type

C/C++ Keyword

Managed Type

C# Keyword

8-bit signed integer

CHAR

char

System.SByte

sbyte

8-bit unsigned integer

BYTE

unsigned char

System.Byte

byte

16-bit signed integer

SHORT 

short 

System.Int16

short

16-bit unsigned integer

WORD and USHORT

unsigned short

System.UInt16

ushort

32-bit signed integer

INT, INT32, LONG, and LONG32

int, long

System.Int32

int

32-bit unsigned integer

DWORD, DWORD32, UINT, and UINT32 

unsigned int, unsigned long

System.UInt32

uint

64-bit signed integer

INT64, LONGLONG, and LONG64

__int64, long long

System.Int64

long

64-bit unsigned integer

DWORDLONG, DWORD64, ULONGLONG, and UINT64

unsigned __int64, unsigned long long

System.UInt64

ulong

Floating-point integer

FLOAT

float

System.Double

double

Source: Codeproject

The table describes what the managed data types are in the native world. 

 

It is important to ask yourself if it is really needed to call native DLL files. I was in a situation where I was going to write a faster algorithm for parsing an int from a byte-array in ASCI-encoding. When I stress tested the code in C++ by using P/invoke to call it form my C# project, it turned out the code was 25% slower. This is due to the overhead caused by the marshaling and the P/invoke. Native code may not always be the solution, especially while developing a managed application. However, a larger algorithm (eg. path finding, cryptography, etc.) which demands more CPU-time, could be running more smoothly.