Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


Hello World Example - Using P.I.P.S.

This example application shows a simple EXE and DLL written using P.I.P.S. (P.I.P.S. Is POSIX on Symbian OS). It also shows the dynamic lookup of symbols by name mechanism used in Unix-like operating systems, instead of the native Symbian OS lookup by ordinal mechanism. P.I.P.S., from Symbian OS v9.3, provides APIs from libdl library to implement this lookup by name mechanism.

The example defines a simple DLL using the P.I.P.S. STDDLL target type, with an exported function. It also creates a simple EXE, using the STDEXE target type, which calls the DLL's exported function using the lookup by name mechanism. These P.I.P.S. specific target types are required to enable the specific options for compilers and linkers to generate P.I.P.S. executables and to make symbol information available in the executable image.

This example is located in examples\PIPS\HelloWorldExample.

[Top]


Description

The following sections provide more information about the example.


Creating a simple DLL using P.I.P.S. STDDLL target type

The example creates a DLL file that declares and defines an exported function. The target type of this DLL file is STDDLL. It contains a header and a source file:


Creating a simple EXE using P.I.P.S. STDEXE target type

The example creates an EXE file which calls the exported function of the loaded DLL. The target type of this EXE file is STDEXE. It calls the following libdl functions to use the lookup by name mechanism:

The EXE links to libdl.lib to use these functions.

[Top]


Build

The Symbian OS build process describes how to build this example application.

The HelloWorldExample builds two files, a DLL file helloworlddllexample.dll, and an EXE file helloworldexeexample.exe, in the standard locations.

To run the example, start helloworldexeexample.exe from the file system or from your IDE. After launching the executable, depending on the emulator you are using, you may need to navigate away from the application launcher or shell screen to view the console.

[Top]


Example code


bld.inf

// bld.inf
// Component description file
//
// Copyright (c) 2007 Symbian Ltd.  All rights reserved.

PRJ_PLATFORMS
DEFAULT 

PRJ_EXPORTS

PRJ_MMPFILES
helloworlddllexample.mmp
helloworldexeexample.mmp

helloworlddllexample.mmp

// helloworlddllexample.mmp
//
// Copyright (C) Symbian Software Ltd 2007.  All rights reserved

TARGET   helloworlddllexample.dll

TARGETTYPE  STDDLL
UID  0x20004C45 0xE80000C5

CAPABILITY NONE
VENDORID     0x70000001

SOURCEPATH    ..\src\helloworlddllexample
SOURCE        helloworlddllexample.c

SYSTEMINCLUDE   \epoc32\include
USERINCLUDE ..\inc\helloworlddllexample

LIBRARY     libc.lib

STATICLIBRARY libcrt0.lib  

helloworldexeexample.mmp

// helloworldexeexample.mmp
//
// Copyright (C) Symbian Software Ltd 2007.  All rights reserved.

TARGET helloworldexeexample.exe

TARGETTYPE STDEXE 
UID 0x20004C45 0xE80000C6

CAPABILITY NONE

SOURCEPATH    ..\src\helloworldexeexample
SOURCE helloworldexeexample.c

SYSTEMINCLUDE   \epoc32\include

USERINCLUDE ..\inc\helloworldexeexample

LIBRARY libc.lib 
LIBRARY libdl.lib

STATICLIBRARY libcrt0.lib

helloworlddllexample.h

// helloworlddllexample.h
//
// Copyright (C) Symbian Software Ltd 2007.  All rights reserved.

#ifndef __HELLOWORLDDLLEXAMPLE_H__
#define __HELLOWORLDDLLEXAMPLE_H__

// Declaration of an export function. 
extern void PrintHelloWorld();

#endif //__HELLOWORLDDLLEXAMPLE_H__

helloworldexeexample.h

// helloworldexeexample.h
//
// Copyright (C) Symbian Software Ltd 2007.  All rights reserved.

#ifndef __HELLOWORLDEXEEXAMPLE_H__
#define __HELLOWORLDEXEEXAMPLE_H__

// Declaration of functions defined in the source file. 
void PressAKey();
int DisplayErrorMessage();

#endif //__HELLOWORLDEXEEXAMPLE_H__

helloworlddllexample.cpp

// helloworlddllexample.cpp
//
// Copyright (C) Symbian Software Ltd 2007.  All rights reserved.
// This example is a simple PIPS STDDLL application that contains the export function definition.
#include "helloworlddllexample.h"
#include <stdio.h>

/*
Definition of the export function declared in the header file.
This function prints a welcome message.
*/
void PrintHelloWorld()
    {
    char str[90]=" Welcome to HelloWorld Basic EXE and DLL example, using symbolic name lookup\n";
    printf("%s",str);
    getchar();
    }

helloworldexeexample.c

// helloworldexeexample.c
//
// Copyright (C) Symbian Software Ltd 2007.  All rights reserved.

/* This example is a simple PIPS STDEXE application. It loads the DLL and calls its exported function. 
The application implements the dynamic lookup by name mechanism of the exported function using the libdl APIs.
*/

// Include files.
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

/**
Waits for key press event.  
*/
void PressAKey()
    {
    fflush(stdout);
    getchar();
    }
/**
Get and display the most recent error that occurred due to any of the dynamic lookup routines.
@return EXIT_FAILURE Returns the failure code.
*/
int DisplayErrorMessage()
    {
    // Obtain the last error occurred using the libdl API, dlerror().
    const char *q = dlerror();
    
    // Prints the error message.
    printf("%s");
    PressAKey();
        
    // returns the failure code.
    return EXIT_FAILURE;
    }

int main()
{
    int result;
    
    // Handle to load the dynamic library.
    void* handleToDll;
    
    typedef void (*PrintHelloWorldFunction)(void);
    PrintHelloWorldFunction PrintHelloWorld;
    
    // Contains name of the DLL file.
    char dllFileName[] = "helloworlddllexample.dll";

    /**
    Loads the DLL using the libdl API dlopen(), to gain access to the symbols in it.
    It takes two parameters: the name of the DLL file and the mode in which it has to be loaded.
    This returns a NULL, if it fails for any reason.Otherwise, it returns a descriptor.
    */
    handleToDll = dlopen(dllFileName, RTLD_LAZY);
    
    // Check the descriptor value.If it is null, the error message is printed.
    if (!handleToDll)
        {
        DisplayErrorMessage();
        }
    
    // Print the message to start the example application.
    printf(" Press enter key to step through the example application\n");
    PressAKey();

    /**
    Locates the symbol using the libdl API, dlsym(). 
    It takes the handle returned by the dlopen() function and the symbol name to find.
    This returns the address binding of the symbol, PrintHelloWorld if successful. Otherwise, it returns NULL.
    */
    PrintHelloWorld = (PrintHelloWorldFunction)dlsym(handleToDll, "PrintHelloWorld");   
    
    // Check the symbol address value. If this is null, the error message is printed.
    if(!PrintHelloWorld)
        {
        DisplayErrorMessage();
        }

    // Call the loaded DLL's exported function.
    PrintHelloWorld();

    /**
    Remove the dlopen-ed handle from the cache, maintained by dlopen(), using libdl API, dlclose().
    It takes the handle returned by the dlopen() function to decrement the reference count associated with the DLL.
    When the reference count reaches zero, the DLL is unloaded from the process address space.
    This API returns 0 if successful, otherwise it returns -1.
    */
    result= dlclose(handleToDll);
    
    // Check the return value. If this is -1, the error message is printed.
    if(result == -1)
        {
        DisplayErrorMessage();
        }
    
    // Print the message to exit from the example application.
    printf(" Press enter key to exit from the example application");
    PressAKey();
    
    // returns the success code.
    return EXIT_SUCCESS;
}