ConsoleApp
From NRCwikis
Making a Symbian Console Application
A console application is an easy way to write some code whole only interaction with the user is to print some stuff to the screen. For this, you can use a Console app.
If you go through the Carbide new project wizard, you'll notice that there is an attractive option there called "Symbian Console Application". This sounds like a great option if all you want to do is debug some algorithm code and print some results to the screen. Unfortunately, the stub Carbide generates for this is broken. The following python scripts make_console_stub.py will generate the correct skeleton code for you. The usage is:
python make_dll_stub.py UID name e.g. python make_dll_stub.py 0xA00001F1 HelloWorld
Note: run this using a windows version of python such as ActivePython. If you use cygwin, you'll have a problem with the sis compiler not understanding your newlines.
To import your newly generated code into Carbide, go to File->Import. Expand the group "Symbian OS" and select "Symbian OS bld.inf file" option. Browse to HelloWorld/group/bld.inf and import this file. This will generate the project for your console app.
What's the difference between a console app and a Symbian GUI app? Well, besides the fact that is has no GUI, it also doesn't create the other normal parts that are used in Symbian apps, in particular the CleanupStack and the ActiveScheduler.
1. You will need to create the CleanupStack yourself. Take a look at the E32Main() function in HelloWorld.cpp file, which creates the CleanupStack as its first statement and destroy it as its last statement.
2. If you are planning to use any ActiveObjects, you'll need to create the ActiveScheduler yourself. This is most likely to happen if you want to use any kind of image reader/decoder classes in Symbian, which are all based on asynchronous calls. See Chapter 9 of Symbian Explained for more information on ActiveObjects.
Project Directories
The stubs generated by the script follow the general structure of a Symbian project. It contains the following directories:
inc and src: contain your code. When you add new .cpp files there Carbide will ask you if you want to add it to your .mmp file. This basically means "do you want this file to be built when you compile the project".
group: contain your build and project settings.
- bld.inf contains a list of makefiles that are used to build your project. Unless you have sub-projects, there will usually just be one makefile listed in the bld.inf. bld.inf is also be file you import into Carbide when you want to import an existing project from the filesystem into your Carbide workspace.
- project.mmp is the actual makefile used by the Symbian build system. The syntax is relatively simple, in general, you list a SOURCEPATH (relative to the group directory) and then a list of sources bo build. You can list multiple SOURCEPATH's to build files from multiple directories.
data: this is the place to put the other files your project needs that are not source files. In addition, this directory contains the project.rss file which is used to make your project appear in the Installed folder correctly when you move it to the phone. The .rss file is bulid into the .rcs file by the RESOURCE line in your .mmp file.
sis: contains project.pkg that is used to build the file project.sisx that you will install to the phone. The pkg file basically contains the directives of the form "take this file on my computer and move it to this directory on the phone". You will at least want to move the application that you compiled (project.exe) and the resource file (project.rcs) to your phone.
Using the Symbian Console
The documentation for the Symbian console class CConsoleBase can be found here and a description of how it is used can be found here.
One thing you will probably want to do is to print to the console from anywhere in your application, not just in the main. You have several options for this. For example, you can make the console global and declare it as extern anywhere you want to use it. Or you can pass it as a parameter to any function that may want to print. A cleaner option is to make a singleton class as shown here:
Console.h:
#ifndef CONSOLE_H_
#define CONSOLE_H_
#include <e32base.h>
#include <e32cons.h>
#include <e32def.h>
//! Single instance class for a Symbian text console
class Console
{
private:
static CConsoleBase* iConsole;
Console();
public:
static CConsoleBase* Self();
static void WaitForKey();
};
#endif /*CONSOLE_H_*/
Console.cpp
#include "Console.h"
CConsoleBase* Console::iConsole = NULL;
CConsoleBase* Console::Self()
{
_LIT(KTxtExampleCode,"Symbian OS Example Code");
if (iConsole == NULL)
{
iConsole = Console::NewL (KTxtExampleCode, TSize (KConsFullScreen,
KConsFullScreen));
}
return iConsole;
}
void Console::WaitForKey()
{
_LIT(KPressAnyKey,"\n[Press any key to continue]\n");
Self()->Printf (KPressAnyKey);
Self()->Getch ();
}
We are using the Singleton pattern here to make sure there is ever only one instance of the console. The instance is accessed by calling Console::Self() method. You can now print from anywhere by adding
#include "Console.h"
at the top of your file and calling
Console::Self()->Printf(_L("Hello world\n"));
You will need to modify the code where you push and pop the console from the cleanup stack by accessing it through the static method. For example, at the top of WrapMainL in HelloWorld.cpp replace:
console=Console::NewL (KTxtExampleCode, TSize (KConsFullScreen, KConsFullScreen)); CleanupStack::PushL (console);
with
CleanupStack::PushL(Console::Self()
and at the end of the same function replace
CleanupStack::PopAndDestroy(1, console)
with
CleanupStack::PopL(Console::Self())
Notice that you don't ever explicitly new the console class, it's done for you by the Self() method.
Happy printf'ing.
