views:

391

answers:

4

I've been given some Symbian C++ code to port over for use with the Android NDK.

The code has lots of Symbian specific code in it and I have very little experience of C++ so its not going very well.

The main thing that is slowing me down is trying to figure out the alternatives to use in normal C++ for the Symbian specific code.

At the minute the compiler is throwing out all sorts of errors for unrecognised types.

From my recent research these are the types that I believe are Symbian specific:

TInt, TBool, TDesc8, RSocket, TInetAddress, TBuf, HBufc, RPointerArray

Changing TInt and TBool to int and bool respectively works in the compiler but I am unsure what to use for the other types?

Can anyone help me out with them? Especially TDesc, TBuf, HBuf and RPointerArray.


Also Symbian has a two phase contructor using

NewL

and

NewLc

But would changing this to a normal C++ constructor be ok?


Finally Symbian uses the clean up stack to help eliminate memory leaks I believe, would removing the clean up stack code be acceptable, I presume it should be replaced with try/catch statements?

+2  A: 

You should try to read some introductory text on development for Symbian. They used to have some examples in the Symbian site, and I am sure that you can find specific docs on how the types you want are meant to be used and what they provide.

The problem is that symbian development has its own idioms that cannot/should not be directly used outside of the symbian environment, as for example the two phase construction with the cleanup stack is unneeded in environments where the compiler has proper exception handling mechanisms --in Symbian a constructor that throws can lead to all sorts of mayhem.

David Rodríguez - dribeas
Thanks David, I have been reading up on Symbian, I feel like I could even code a basic program in it by now :) , Problem is that I've had to learn C++ syntax and ideas at the same time and I am now unsure as to how to change say Tdesc, RPointerArray into something that will compile in normal C++ (libc)
Donal Rafferty
I did some Symbian C++ back in 2003, so I don't remember that much. If I recall correctly TDesc family of types were used for strings, and if you can you should use `std::string`, but conversion will not be straight forward. You might want to consider using C-style strings (const char*) as they are probably closer to what TDesc are. RPointerArray is an array of pointers whose memory is managed somewhere else. Depending on how much refactoring you want to do, you can replace it by an array of pointers, or convert the application to use smart pointers (safer, quite more work to be done there)
David Rodríguez - dribeas
Thanks David, Char seems to be a good replacement for TDesc, working on RPointerArrays at the minute and they are pretty troublesome, also what are HBufc's? I presume there some sort of buffer?
Donal Rafferty
+1  A: 

It would typically be a bad idea to try and port Symbian OS C++ to standard C++ without having a very good understanding of what the Symbian idioms do.

This could very well be one of these projects where the right thing to do is to rewrite most of the code pretty much from scratch. If you barely know the language you are targetting, there is little point in deluding yourself into thinking you won't make mistakes, waste time and throw away new code anyway. It's all part of learning.

The CleanupStack mechanism is meant to help you deal with anything that could go wrong, including power outage and out of memory conditions. Technically, these days, it is implemented as C++ exceptions but it covers more than the usual error cases standard C++ code normally handles.

Descriptors (TDesc, TBuf and HBuf all belong to the descriptor class hierarchy) and templates (arrays, queues, lists...) predate their equivalent in standard C++ while dealing with issues like the CleanupStack, coding standards, memory management and integrity...

A relevant plug if you want to learn about it: Quick Recipes On Symbian OS is a recent attempt at explaning it all in as few pages as possible.

You should also definitely look at the Foundation website to get started.

Classes prefixed by T are meant to be small enough by themselves that they can be allocated on the stack.

Descriptor classes suffixed by C are meant to be immutable (A mutable descriptor can usually be created from them, though).

HBufC is pretty much the only Symbian class prefixed by H. It should always be allocated on the Heap.

A method suffixed by C will add an object on the CleanupStack when it returns successfully (usually, it's the object it returns). It's up to the calling code to Pop that object.

Classes prefixed by R are meant to be allocated on the stack but manage their own heap-based resources. They usually have some kind of Close() method that needs to be called before their destructor.

A typical way to thing about the differences between a collection of objects and a collection of pointers to object is who owns the objects in the collection. Either the collection owns the objects when they are added and looses them when they are removed (and is therefore responsible for deleting each object it still contains when it is itself destroyed) or the collection doesn't transfer ownership and something else must ensure the objects it contains will stay valid during the collection's lifetime.

Another way to think about collections is about how much copying of objects you want to happen when you add/get objects to/from the collection.

Symbian descriptor and collection classes are meant to cover all these different ways of using memory and let you choose the one you need based on what you want to do.

It's certainly not easy to do it right but that's how this operating system works.

QuickRecipesOnSymbianOS
Excellent post, thanks very much
Donal Rafferty
+2  A: 

If this is not a very large codebase it may be easier/faster to start from scratch and doing everything Android style. Even if you require NDK/C++ this approach may be quicker.

Another approach may be to use portable C/C++ for the core, and the use this on both Symbian and Android version while doing UI stuff separately for each platform. Spotify have done this on Android and iPhone.

alexanderblom
Thanks, I have stopped trying to port the Symbian C++ as it is too difficult for a large codebase and reevaluating the options
Donal Rafferty
Also, writing standard, portable C++ feels a lot better, altough your boss might not buy that argument.
Viktor Sehr
+1  A: 

I'm not sure whether you're still interested, but one possibility is that where the Symbian idioms are using the EUSER.DLL (i.e. TDesC derived classes, RPointer*, etc) you may find taking the open source EPL code from Symbian developer site and adding it directly into your port a viable option. That is port over the necessary bits of EUSER (and others perhaps?).

However, if your current code base already uses a lot of the other subsystems you're going to see this become very unwieldy.

David Crookes