diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/PDK/Source/GUID-9D278187-8B5E-581D-9869-EE8861048F93.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/PDK/Source/GUID-9D278187-8B5E-581D-9869-EE8861048F93.dita Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,190 @@ + + + + + +Dynamic +Link Libraries +
Introduction

A +Dynamic Link Library (DLL) contains an executable code that can be shared +by many processes in a system at any one time. A program can link against +a DLL at compile time, meaning that the linker will match the DLL's symbols +(such as function names and variables) with references from the program and +ascertain the address within the DLL of the functions or variables.

Alternatively +a program can dynamically load a DLL into memory during execution, locate +the address of a symbol, use it and then unload the DLL. Traditionally and +for greater memory efficiency, Symbian platform links by ordinal, whereas +Unix-like operating systems link by name. The following sections provide example +code to illustrate how the DLL loader works with each operating system.

The +Symbian platform v9.3 kernel supports all functionalities of P.I.P.S. libraries +- referred to as "P.I.P.S.- ready". Pre v9.3 the kernel only supports the +Symbian platform- standard ordinal lookup in DLLs; it does not support symbolic +lookup. Thus the function dlsym() cannot be used with a symbolic +name. To overcome this restriction, 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. For example, instead of: dlsym(&handle, +"foo") use dlsym (&handle, "3") where the function foo() has +ordinal 3.

+
Using shared +libraries in a Unix-like environment

The following code shows how +a shared library is dynamically loaded and used in a Unix-like environment +using the dl interface.

int main(int argc, char *argv[]) +{ + //Handle + void* dll_handle; + + //Function prototype + void (*printSum)(int a, int b); + + //Error message + const char* errorMsg; + + //Filename of dll to load + char dllFileName[] = "/root/PortDoc/Example6/dll/shareddll"; + + //Load the dll + dll_handle = dlopen(dllFileName, RTLD_LAZY); + if (!dll_handle) + { + fprintf(stderr, "Error during load of library: %s\n", dlerror()); + return EXIT_FAILURE; + } + + //Find the symbol + printSum = dlsym(dll_handle, "printSum"); + + //Get the error message + errorMsg = dlerror(); + if (errorMsg) + { + fprintf(stderr, "Error during symbol lookup: %s\n", errorMsg); + return EXIT_FAILURE; + } + + //Now call the function + printSum(4, 6); + + //Dispose of the DLL + dlclose(dll_handle); + + return EXIT_SUCCESS; +} +

As an example, the shareddll might have a +function such as:

void printSum(int a, int b) + { + printf("Result is : %d\n", a + b); + }
+
DLLs on Symbian +platform(prior to v9.3)

Symbian platform programs uses the function +or variable's ordinal position within a DLL to link with DLLs. For example, +implementing a shared DLL on Symbian platform could look like this:

EXPORT_C void printSum(int a, int b) + { + printf("Result is : %d\n", a + b); + }

Compiling this will generate a .def file, +which contains the ordinals of each symbol in the DLL. For instance:

EXPORTS + printSum @ 1 NONAME

Here, the .def shows +that the ordinal for the printSum() function is 1.

The +following code shows how the main() function is changed in +P.I.P.S..

int main(int argc, char *argv[]) +{ + //Handle + void* dll_handle; + + //Function prototype + void (*printSum)(int a, int b); + + //Error message + const char* errorMsg; + + //Filename of dll to load + char dllFileName[] = "/root/PortDoc/Example6/dll/shareddll"; + + //Load the dll + dll_handle = dlopen(dllFileName, RTLD_LAZY); + if (!dll_handle) + { + fprintf(stderr, "Error during load of library: %s\n", dlerror()); + return EXIT_FAILURE; + } + + //Find the symbol, using the ordinal + printSum = dlsym(dll_handle, "1"); + + //Get the error message + errorMsg = dlerror(); + if (errorMsg) + { + fprintf(stderr, "Error during symbol lookup: %s\n", errorMsg); + return EXIT_FAILURE; + } + + //Now call the function + printSum(4, 6); + + //Dispose of the DLL + dlclose(dll_handle); + + return EXIT_SUCCESS; +} +

Note that for the Symbian library loader, the mode parameter +for the dlopen() function is irrelevant and the library +will be loaded immediately. So although RTLD_LAZY is the +mode parameter in the example, it will behave just as RTLD_NOW. +Also note that there is no facility to call any library constructor and destructor +functions using __attribute((constructor)) or __attribute((destructor)).

+
DLLs on Symbian +platform (v9.3 onwards)

P.I.P.S. provides APIs from libdl to support +dynamic lookup by name, which is used in Unix-like platforms, instead of the +native Symbian platform lookup by ordinal mechanism. Lookup by name is possible +thanks to the new libdl, which in turn uses the existing RLibrary functions +to load and unload DLLs.

A symbol name lookup version of the dlsym() +function is provided, similar to UNIX®, which does not need any special treatment +(the example shown in the Using Shared libraries in a Unix-like environment section +will suffice). However, it is still necessary to generate the .def file +for the DLL. The following sections provides a brief summary of the functionality +provided by libdl.

The libdl APIs, +which support dynamic lookup by name, are described in the following table:

+ + + +

libdl API

+

Description

+
+ +void *dlopen (const char *path, int mode) +

Call dlopen() to gain access to symbols of any +shared library or DLL. If dlopen() fails for any reason, +it will return a NULL. The default search path for the library can be provided +in the environment variable LD_LIBRARY_PATH.

+
+ +void *dlsym(void *handle, const char *symbol) +

The dlsym() function returns the address binding +of the symbol described in the null-terminated character string 'symbol', +as it occurs in the shared object identified by 'handle'.

+
+ +int dlclose(void *handle) +

Call dlclose() with a valid dlopen-ed handle +to remove it from the cache list maintained by dlopen(). +If it fails, dlclose() will return -1; otherwise, it will return 0.

+
+ +char *dlerror(void) +

Call dlerror() to obtain the most recent error +that occurred due to any of the dl routines, that is, dlopen(), dlsym(), +or dlclose().

+
+ + +

+
+ +One Definition Rule - warning +
\ No newline at end of file