×
Namespaces

Variants
Actions

Archived:Creating C PySymbian extensions using Carbide.c++

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

This tutorial explains how to make PySymbian extensions using Carbide.c++.

Article Metadata
Code Example
Source file: Media:None.zip
Compatibility
Platform(s):
S60 3rd Edition FP2
Article
Created: diegodobelo (10 Jan 2009)
Last edited: hamishwillee (31 May 2013)
{{{width}}}
18 Jan
2009


Contents

Preconditions

First, install the Nokia S60 Platform SDKs for Symbian OS, which can be found here. (In this tutorial we used the S60 3rd Edition, FP2 v1.1 SDK). These SDKs contain some files needed to compile the extension. However, they do not contain Python files, such as python.h and python222.lib. To add these important files, install the PySymbian SDKs on an installed S60 SDK. First, get PythonForS60_X_X_X_SDK_3rdEd.zip here, where X is the version of the package (in this tutorial we used PySymbian v1.4.5). Next, unzip the contents of the internal zip file (named sdk_files.zip) into the SDK folder (in this case, C:\S60\devices\S60_3rd_FP2_SDK_v1.1). This operation will add Python files to the D:\S60\devices\S60_3rd_FP2_SDK_v1.1\epoc32 folder.

After installing the SDK and Python files, install Carbide.c++, which is an excellent integrated development environment (IDE) to create C/C++ software for the S60 platform. The Carbide.c++ installation file can be found here.

Importing the example

Now, get the example package here and unzip it.

Open Carbide.c++ and go to File->;Import. Chose Symbian OS->;Symbian OS Bld.inf file and click the Next button.


Project1.JPG

Browse the bld.inf file, which is in the group folder located in the unzipped example package and click Next.

Bldinf.JPG

Choose Phone Release (GCCE) and click Next and Finish.

Gcce.JPG

Now you can see the example files.

Files.JPG

This is a very simple example showing an empty information note.

Analysing the example

The project includes, the most important files to be analyzed here are none.h and none.cpp.

In the none.h file we have included a few useful header files.

  • e32base.h: For CBase;
  • e32std.h: For descriptors;
  • aknnotewrappers.h: For notes (remember, our example uses an information note);
  • Python.h: For Python issues;
  • symbian_python_ext_util.h: For error handling.
#ifndef __NONE_H__
#define __NONE_H__
 
// Include Files
 
#include // CBase
#include // TBuf
#include
#include "Python.h"
#include "symbian_python_ext_util.h"
 
// Class Definitions
 
class Cnone : public CBase
{
public:
// new functions
IMPORT_C static Cnone* NewL();
IMPORT_C static Cnone* NewLC();
IMPORT_C ~Cnone();
 
public: // new functions, example API
IMPORT_C void ShowConfirmationNote();
 
private: // new functions
Cnone();
void ConstructL();
 
private: // data
};
 
#endif // __NONE_H__

Other items in this file are constructors and methods definitions, such as the ShowConfirmationNote() method.

In the none.cpp file you can see the include statement of none.h. Going down, you’ll see the ShowConfirmationNote() method, which only calls the ExecuteLD() method of a CAknInformationNote object. This function does what we want (the execution of an empty information note), but it cannot be called directly from Python. Thus, you must create a function that is callable from Python. This function receives Python parameters, converts these parameters to C language, calls Symbian C++ methods, and returns a Python object to the caller.

#include "none.h"	// Cnone
#include "none.pan" // panic codes
 
// Member Functions
 
EXPORT_C Cnone* Cnone::NewLC()
{
Cnone* self = new (ELeave) Cnone;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
 
EXPORT_C Cnone* Cnone::NewL()
{
Cnone* self = Cnone::NewLC();
CleanupStack::Pop(self);
return self;
}
 
Cnone::Cnone()
// note, CBase initialises all member variables to zero
{
}
 
void Cnone::ConstructL()
{
}
 
EXPORT_C Cnone::~Cnone()
{
}
 
EXPORT_C void Cnone::ShowConfirmationNote()
{
CAknInformationNote* dialog = new(ELeave)CAknInformationNote();
dialog->ExecuteLD();
}
 
static PyObject* show_note(PyObject* /*self*/, PyObject* args)
{
 
TInt error;
Cnone* obj = Cnone::NewL();
TRAP(error, obj->ShowConfirmationNote());
if (error)
return SPyErr_SetFromSymbianOSErr(error);
delete obj;
Py_INCREF(Py_None);
return Py_None;
}
 
static const PyMethodDef none_methods[] =
{
{
"show_note", (PyCFunction)show_note, METH_VARARGS, "shows a note."
},
{
0, 0
}
};
 
DL_EXPORT(void) init_none()
{
Py_InitModule("none", (PyMethodDef*) none_methods);
}

The show_note function receives two PyObject parameters. The first is the self parameter and the second is the tuple containing arguments. In the body of this function we call the ShowConfirmationNote method into a TRAP. The TRAP pulls a nonzero error code into an integer if an error has occurred. The SPyErr_SetFromSymbianOSErr(error) statement is called if an error has occurred. It just converts Symbian OS errors to Python errors. If no errors occurred, the note will be displayed and the function will return a Py_None.

Next, we have a PyMethodDef, which is a table containing Python function names to their C function implementations. It also has a flag telling the interpreter the calling convention to be used for the C function. Normally it should always be "METH_VARARGS" or "METH_VARARGS | METH_KEYWORDS". If you wish to add more functions, you will need to add these functions to this table.

The next function is init_none(). This function passes the method table to the interpreter in the module's initialisation function. The initialisation function must be named initname(), where name is the name of the module and should be the only non-static item defined in the module file. It calls the function Py_InitModule, which receives the module name and table name described above.

Building the example

First, using Carbide.c++, go to the group folder and open none.mmp file. In the Overview tab we have Target name (none.pyd), Target type (DLL), and UID 2 (must be 0x1000008d).

Overview.JPG

Open the Libraries tab and add euser.lib, python222.lib, avkon.lib, eikcdlg.lib, and eikctl.lib libraries.

Libraries.JPG

Open the Options tab and add these paths to System includes (under Compiler Settings): \epoc32\include, \epoc32\include\libc and \epoc32\include\python. Also add these capabilities: LocalServices, NetworkServices, ReadUserData, UserEnvironment, and WriteUserData.

Mmpoptions.JPG

Go to menu Project->Properties. Then expand the Carbide.c++ option and select Build Configurations.

Pkgproperties.JPG

On the SIS Builder tab, click the Add button and browse the ‘.pkg’ file (which is under sis folder). Choose the Output File Name and select the Don't sign sis file. Click the OK button.

Sisoptions.JPG

Go to menu Project->Freeze Exports. Finally, go to menu Project->Build Project.

Postconditions

If everything runs without problems, the sis file will be created and placed inside the sis folder.

This page was last modified on 31 May 2013, at 04:07.
151 page views in the last 30 days.