Writing a DLL (used in Symbian OS)
A DLL (Dynamic Link Library) is a piece of code (a library) that is linked to a program at runtime rather than during the build process. The code inside a DLL can be shared by several clients at the same time without being duplicated in the mobile memory.
Static Interface vs Polymorphic InterfaceSymbian OS supports two types of DLLs :
Static Interface DLL
Polymorphic Interface DLL
A static interface DLL is automatically loaded in the mobile RAM memory when a program that use it is started (except if it is in ROM where it is executed in place). It is also automatically unloaded when nobody needs it anymore. The static interface DLL provides a unique set of function within the system (i.e. two DLLs with the same exported function could not coexist in the system). Static interface DLLs have .dll file extension and are commonly used to implements application engines (i.e. UI independent code) in Symbian OS.
A polymorphic interface DLL is loaded explicitly by calling RLibrary::Load() and shall be unloaded using RLibrary::Close(). Several polymorphic DLLs can expose the same interface to their clients. So this kind of DLLs is generally used by a framework to provide plug-ins facility. Polymorphic Interface DLLs can have several different file extensions in Symbian OS. The most known one being .app (applications), .ldd (logical device drivers, .tsy and .csy (telephony and communication server modules),...
We will only focus on static interface DLLs which is the most common type of DLLs you (and I!) have to write. We will use the generic DLL term in the rest of the article.
A Static Interface DLLFrom a client point of view, a DLL is made of three files:
a header file, which as .h file extension and which is #included by the client and needed at compilation time.
a import library file (.lib file extension) which the client links againts. This file contains the interface provided by the DLL.
the DLL itself (.dll file extension) which contain the implementation of all functions of the DLL and an export table so that the link can be completed at execution time.
From the provider point a view, the DLL can be seen as a complete Symbian project. It shall have:
its own MMP file (listed in a bld.inf file)
a header file that specifies the interface
source code file(s) that contain the implementation.
The header fileA DLL header file is very similar to other classes header files. The important thing to remember is to use the IMPORT_C macro in the declarations of all functions to be exported:
class CMyEngine : public CBase
// These functions are visible by the
// clients of the DLL and needs to have
// the IMPORT_C tag
IMPORT_C static CMyEngine* NewL();
IMPORT_C static CMyEngine* NewLC();
IMPORT_C void MyPublicMethod();
IMPORT_C void AnotherPublicMethod();
// These functions are not visible by the
// clients of the DLL and then do not need
// the IMPORT_C tag
The implementation fileWriting a DLL has not many impact on code in itself. But there are two important points to respect:
an implementation for the E32Dll() function shall be provided (see code below).
another specific macro, EXPORT_C, should be added in front of each exported function implementation. :
// This function is mandatory for all DLLs
EXPORT_C TInt E32Dll(TDllReason)
// This function is exported: The EXPORT_C tag shall be used.
EXPORT_C void MyPublicMethod()
// This one is not: The EXPORT_C tag shall not be used.
// Do Something
The MMP fileThe MMP file for the DLL should:
define the project’s target type as dll
use the appropriate UID2 value (0x1000008d)
During development phasesn, you should also tell the build environment that DLL interface is not finalised by using the EXPORTUNFROZEN primitive:
UID 0x1000008d <myUID3>
Freezing the DLL interfaceOnce you have finished your development, and before releasing versions of your DLL, you should freeze the interface, so as to ensure the backward compatibility of future releases of a library.
To do this, remove the exportunfrozen keyword from your MMP file and build the project in the normal way: a warning will be generated to the effect that the frozen .def file does not yet exist. Once the project has been built you can freeze by using:
Note that all ARM platforms share a common .def file, but that WINS/WINSCW has a different .def file.
Once the project is frozen, regenerate the makefiles so that the import library will be created directly from the frozen .def file.