This section addresses the basic differences in the way things are done in Symbian Platform and in Linux.
In Symbian platform, project source files are arranged based on the directory pattern shown below.
Directory |
Description |
src |
Contains all the source files of the project. |
inc |
Contains all the header files of the project. |
group |
Contains MMP files, and bld.inf. |
The developer can choose whether to follow these tips.
This applies only for the DLL
target type. If a DLL wants to export an API, the code definition should start
with the macro EXPORT_C
.
// Declaration #ifdef SYMBIAN #define GLOBAL(type) EXPORT_C type #else #define GLOBAL(type) type #endif // SYMBIAN // Definition GLOBAL(void) jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize) { int i; /* Guard against version mismatches between library and caller. */ cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ if (version != JPEG_LIB_VERSION) ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); if (structsize != SIZEOF(struct jpeg_decompress_struct)) ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize); ... }
Whenever a DLL is built on Symbian platform, it creates three files:
<target>.dll
is the actual DLL that gets loaded
at runtime
<target>.lib
is the static library which contains
wrappers for each DLL exported function that, when run, will locate and execute
the real function’s code in the appropriate runtime-loaded DLL.
<target.def>
gets created when the user executes
abld freeze. The .def
file contains the list of exported
DLL functions along with their ordinal numbers. Symbian platform does not
store exported symbol names in DLL; instead, the exported functions are referenced
using only their ordinal numbers. Storing the ordinal numbers instead of names
reduces the size of the DLL.
The following is a sample .def
file created for libjpeg
:
EXPORTS jcopy_block_row @ 1 NONAME jcopy_sample_rows @ 2 NONAME jdiv_round_up @ 3 NONAME jinit_1pass_quantizer @ 4 NONAME jinit_2pass_quantizer @ 5 NONAME jinit_c_coef_controller @ 6 NONAME jinit_c_main_controller @ 7 NONAME jinit_c_master_control @ 8 NONAME jinit_c_prep_controller @ 9 NONAME jinit_color_converter @ 10 NONAME
The following example shows how to declare and define an exportable function from a DLL and to make it callable from a Symbian C++ application:
In xxx.h
#ifdef __cplusplus extern "C" #endif IMPORT_C int Foo();
In xxx.c
extern "C" EXPORT_C int Foo() { return something; }
dlsym()
or g_module_symbol()
Since DLL entry points are not exported by name, DLL symbol lookup functions do not work on Symbian platform. For more information about alternatives suggested on Symbian platform, see Dynamic Link Libraries.
The functions dlsym()
from libdl
and g_module_symbol()
from GLib are examples of such functions. Look for usage of these functions
in the OSS port and change the code.
ret = g_module_symbol (module, "jinit_c_prep_controller", &ptr);
needs to be changed to:
ret = g_module_symbol (module, "9", &ptr);
For
example, for dlsym()
pass the function's ordinal number as
symbol parameter (refer the library's list of exports, the DEF file for the
function's ordinal number):
dlsym(&handle, "foo")
needs to be changed to:
dlsym (&handle, "3")
This section suggests a way to overcome the problems faced when macros with a variable list of arguments are used.
#define DEBUG(a,...)
The above statement causes a compilation error. One of the solutions to solve this problem is as follows:
#define DEBUG _DEBUG static inline void _DEBUG (const char *a, ...) { }
While porting the OSS code, keep the changes to the OSS code as few as possible. The OSS code is already tested and used by a bigger community, and is unlikely to have any compilation errors or major logical errors. In many cases code changes that are necessary brings potential logical flaws to the OSS port. Minimum changes to the OSS code while porting also helps in merging to the new OSS.
Exporting data from a DLL is not allowed in Symbian platform . The following pattern can be used:
Do not export global variables. Within DLL, there is one global variable, for example:
int globalVal;
Export one method that returns a pointer to that variable.
extern "C" EXPORT_C int* GlbData () { return &globalVal }
Define a macro for the
user of the DLL. See the example below. Within the DLL header (for example, xxx.h
),
define the following:
#ifdef __cplusplus extern "C" #endif IMPORT_C int* GlbData (); #define globalVal (*GlbData())
The absence of the dependent libraries could
be one of the reasons for the application not to load in the mobile device.
On the target device, Symbian platform looks for libraries in c:\sys\bin
or
in z:\sys\bin
.
Do make sure that all the libraries are present in either of the above-mentioned libraries.
Capabilities are specified in the MMP file. The
primary information source is the P.I.P.S. API reference documentation. If
problems with capabilities remain, one known method to find the capability
is to analyze the [Debug Messages] window in CodeWarrior IDE (while debugging).
During development, CAPABILITY All –Tcb
is acceptable, but
for release code it is good practice to give a valid capability in the MMP
file in order to have the application successfully signed. The following is
a sample of a capability error found in the [Debug Messages] window.
*PlatSec* ERROR - Capability check failed - Process hellogst.exe[10015942]0001 was checked by Thread c32exe.exe[101f7989]0001::ESock_IP and was found to be missing the capabilities: NetworkServices.
At the moment, environment variables are not completely
supported in Symbian C++. Therefore be wary of using library functions like getenv()
which
work on environment variables. Make sure the library initialization routine
calls setenv()
with the proper value of the environment variable.
Also, be wary of functions like g_get_home_dir()
which may
not work as they behave in Linux.
if ((memenv = getenv("JPEGMEM")) != NULL) // will not work properly
Suggested change:
void LibraryInit() { setenv ("JPEGMEM ", "XXXXX", 1); }
The syntax for inline assembly code is different in Symbian platform. The following is a code snippet of assembly code syntax in Symbian platform.
EXPORT_C __NAKED__ TUint16 TTemplate::Register16(TUint anAddr) /** Read a 16-bit register @returns register contents */ { asm("ldrh r0,[r0]"); __JUMP(,lr); }
In common practice the assembly code has the extension .CIA
in
Symbian platform, whereas in Linux the assembly code has the extension .S
.
The following table lists terms used in Linux and their approximate equivalents in Symbian platform:
Linux |
Symbian |
|
|
|
|
|
DLL |
|
LIB |
Makefile |
MMP file |
SOURCES of Makefile |
SOURCE of the MMP file |
|
|
|
|
The following table lists a few important things about the Symbian platform: