S60 Open C
Porting Illustrated: Effective Guide to OSS Porting using Open C

Porting Illustrated: Effective Guide to OSS Porting using Open C

Table of Contents

Troubleshooting - some tips and tricks
Symbian directory structure
EXPORT_C, DEF file and ordinal numbers
dlsym or g_module_symbol
Problem with a variable list of arguments in macros
Symbian compiler performs strict type checking
Keep changes to OSS to a minimum
Exporting variables from a DLL
Application is not loaded
Dynamic array allocation
Capabilities not known
Environment variables
Assembly code
Glossary

 


Troubleshooting - some tips and tricks

This section addresses the basic differences in the way things are done in Symbian OS and in Linux.

 


Symbian directory structure

In Symbian OS, project source files are arranged based on the directory pattern sown 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 this strictly.

 


EXPORT_C, DEF file and ordinal numbers

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 OS, 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 OS 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 in Symbian OS. 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. For example:

ret = g_module_symbol (module, "jinit_c_prep_controller", &ptr); 

needs to be changed to:

ret = g_module_symbol (module, "9", &ptr);

 


Problem with a variable list of arguments in macros

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, ...) 
{ 
}

 


Symbian compiler performs strict type checking

Type casting is typically required in many places in OSS code. Sometimes preprocessing a particular file and analyzing the preprocessed file gives many hints about the possible errors.

Consider the following code snippet:

char * buf=”hello world”;
 int i= buf;
The code compiles with a warning with GCC compiler on Linux but gives rise to an error with Symbian compiler.

 


Keep changes to OSS to a minimum

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 variables from a DLL

Exporting data from a DLL is not allowed in Symbian OS . The following pattern can be used:

  1. Do not export global variables.
  2. Export one method that returns a pointer to that variable.
  3. Define a macro for the user of the DLL. See the example below

1. Do not export global variables.

Within DLL, there is one global variable, for example:

int globalVal; 

2. Export one method that returns a pointer to that variable

extern "C" EXPORT_C int* GlbData ()
    {
    return &globalVal
    }

3. Define a macro for the user of the DLL

Within the DLL header (e.g.,xxx.h), define the following:
#ifdef __cplusplus
extern "C" 
#endif
IMPORT_C int* GlbData ();
#define globalVal (*GlbData())

 


Application is not loaded

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 OS 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.

 


Dynamic array allocation

Statements such as int counts[2*size]; are not allowed in Symbian C++. An alternative would be to create counts dynamically and free the memory after its usage.

 


Capabilities not known

Capabilities are specified in the MMP file. The primary information source is the Open C 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. 

 


Environment variables

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);  
}

 


Assembly code

The syntax for inline assembly code is different in Symbian OS. The following is a code snippet of assembly code syntax in Symbian OS.

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 OS, whereas in Linux the assembly code has the extension .S.

 


Glossary

The following table lists terms used in Linux and their approximate equivalents in Symbian OS:

Linux Symbian
-D of Makefile MACRO of theMMP file
-I of Makefile USERINCLUDE of the MMP file
SO DLL
A LIB
Makefile MMP file
SOURCES of Makefile SOURCE of the MMP file
/usr/include/ \EPOC32\INCLUDE
/usr/lib/ \epoc32\data\c\sys\bin on an emulator, \sys\bin on a target device

The following table lists a few important things about the Symbian OS:

ABI_DIR Platform, e.g., winscw or armv5
BUILD_DIR UDEB or UREL
c: drive in emulator \epoc32\data\c and \epoc32\winscw\c
z: drive in emulator Z:\epoc32\data\z
bld.inf Lists public header files and their location in \EPOC32\INCLUDE

Give feedback of this section


©Nokia 2007

Back to top


This material, including documentation and any related computer programs, is protected by copyright controlled by Nokia. All rights are reserved. Copying, including reproducing, storing, adapting or translating, any or all of this material requires the prior written consent of Nokia. This material also contains confidential information, which may not be disclosed to others without the prior written consent of Nokia.

Nokia is a registered trademark of Nokia Corporation. S60 and logo is a trademark of Nokia Corporation. Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. Other company and product names mentioned herein may be trademarks or tradenames of their respective owners.