Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Full Power on the Phone

0.00/5 (No votes)
27 May 2014 1  
Emporing C++ on the Windows Phone 8.0

Introduction

Windows Phone 8 is a somehow unknown platform but it works like Windows on the desktop in many ways. So it would be very handy to get desktop code running and doing the hard work and only generate a new UI. The content expanded under my fingers and so a real bunch of interesting technologies are here unveiled which I discovered by Googling the internet which are resulting in that tiny App.

Background

I have been working a lot on the iPhone but wondering what the Windows Phone can do. So I read some links and found a sample from Microsoft which led the way to create the DLL which serves the C# UI.

The Big Picture

A picture says more than a thousand words, so I provided one clearly to describe my software architecture.

For who is real curious: rename the xap to a zip and expand it to see the content.

Interesting Points of the Code

It is a lot inside, but the main goal is to showcase you to access some C++ threads and fetching the data to the C# UI in a nonblocking way.

The Easy Part in C#

To wire up the UI, we set a callback to get an update when data from the working thread arrives.

//Callback if new data arrived
worker.OnNewData += worker_OnNewData; 

The callback got called from the C++ thread in the NativeWorker class.

//Propagating the new Data to the UI
OnNewData( this, new PropertyChangedEventArgs( "DataBuffer" ) ); 

After the new data is read and ready to get presented, more interesting is the data transfer via the Buffer class. It looks simple in C# but got tricky in C++.

Windows.Storage.Streams.Buffer iBuffer = new Windows.Storage.Streams.Buffer( (uint) count );
//this is the final call to get data from the component 
runtime.FillBuffer( iBuffer );
DataReader reader = DataReader.FromBuffer(iBuffer); 

To get a responsive UI, we need threading. That also makes this architecture interesting for streaming or communication projects.

Thread workerThread = new Thread( runtime.StartStream ); 
// Start the worker thread.
 workerThread.Start(); 

And now, we are ready for the harder stuff.

The Harder Part in C#

The C++ component exposes an interface and class which we imported per reference.

So we can create an object and access the functions.

public static NativeBackend runtime = null;//only one
runtime = new NativeBackend();
runtime.setCallback( this );
runtime.SetUrl( s );

And we implement the interfaces, so it can get called from C++ if new data arrives.

The Easy Part in C++

The easy part in C++ is the C# interface in C++. It is the layer which is "visible" to C#: interface and the class. Inside of the class runs the native C++. It is important that the top-most namespace is the same as the name of the component. Microsoft knows why - I'm not.

 namespace WPComponent
{
    public interface class INativeInterface
    {
        void OnNewState(Platform::String^ state);
        void OnSendData(int count);
    }; 

This interface is also implemented in C#:

class NativeWorker : INativeInterface

And here starts the class:

public ref class NativeBackend sealed

The mysterious keywords are needed to expose the class properly in the Windows Runtime.

The Filthy Part in C++

I want to express some anger about the Microsoft classes because in the Apple world much is going really smarter. The Apple guys name that "boiler plate code" and hate it. I hate it also because "you only live once".

size_t Len = url->Length();
char *Data = new char[Len+1];
wcstombs_s( &Len, Data, Len+1, url->Data(), Len ); 

In Apple, is it one call (message) to the NSString object and you are done. Yeah!!!

char* Data = [url UTF8String];

The Hard Part in C++

The hard part in C++ is the Run() function. In my demonstration, it only waits and fills a buffer. Here is point in all coders can do their heavy work: downloading, processing or uploading. For an upload, the Buffer transfer only needs to be the other direction.

do
{
    //do the hard work
    i++;
    DWORD wait = WaitForSingleObjectEx( hWait, 1000, 0 );
    //::SetEvent(hWait);
    //prepare some output
    int count = sprintf_s( buffer, "%s. Here it comes from C++ %ld\n", Data, i );

    SendData( (BYTE*) buffer, count );
}
while( Running ); 

The Hardest Part in C++

The hardest part in C++ is the function which copies the bits from C++ to the C# interface. The reason is that is a big deal copying real memory native bits into the managed runtime. It is "COM at its best" and works with smart pointers. I found this outstanding solution here.

ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
// Query the IBufferByteAccess interface.
reinterpret_cast<IInspectable*>(iBuffer)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));

if( bufferByteAccess != NULL )
{
    byte* dest = nullptr;
    bufferByteAccess->Buffer(&dest);
    memcpy( dest, m_pBuffer, m_nBuffer );
    iBuffer->Length = m_nBuffer;
} 

To understand it, you need to know about IInspectable which bridges between the "code worlds". This code really rocks.

One More Thing

Debugging works fine, but you need to choose whether debugging the managed code or the native code. Here is a screenshot where you can switch.

Points of Interest

It shows that Windows Phone is really an interesting and powerful platform which has huge potential and to which a lot of C++ code can get adopted with not much huzzle. In that way, a lot of big libraries could get to work like PJSIP or Live 555. The PJSIP has also a own version of its stack for Windows Phone which only needs to be referenced.

History

  • Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here