PathEngine home previous: Linking with the PathEngine DLLnext: Linking with PathEngine Statically
Contents, Programmers Guide, Linking with the SDK, Dynamic Linking on GCC Based Platforms

Dynamic Linking on GCC Based Platforms

The GCC based build setup generates a .so file instead of a .dll.
This is essentially a Linux equivalent to a Windows dll.

The following code shows how PathEngine can be loaded as a .so, and an entry point obtained:

#include "i_pathengine.h"
#include "PathEngine_DirectLinkage.h"
#include <dlfcn.h>
#include <stdio.h>
#include <signal.h>

class cErrorHandler : public iErrorHandler
{
public:
    eAction handle(const char* type, const char* description, const char *const* attributes)
    {
        printf("Error handler called:\n");
        printf(type);
        printf("\n");
        printf(description);
        printf("\n");
        raise(SIGTRAP);
        return CONTINUE;
    }
};

cErrorHandler gErrorHandler;

int
main (int argc, char* argv[])
{
    const char* errorString;

    void* handle = dlopen("./PathEngine.so", RTLD_NOW);
    if(!handle)
    {
        printf("!handle\n");
        errorString = dlerror();
        if(errorString)
        {
            printf(errorString);
        }
        return 1;
    }

    iPathEngine* (*PathEngine_InitialiseAndObtainRootInterface_Pointer)(iErrorHandler*);
    void (*PathEngine_ShutDown_Pointer)();

    dlerror();
    *(void **)(&PathEngine_InitialiseAndObtainRootInterface_Pointer) = dlsym(handle, "PathEngine_InitialiseAndObtainRootInterface");
    errorString = dlerror();
    if(errorString)
    {
        printf(errorString);
        printf("\n");
        dlclose(handle);
        return 1;
    }
    *(void **)(&PathEngine_ShutDown_Pointer) = dlsym(handle, "PathEngine_ShutDown");
    errorString = dlerror();
    if(errorString)
    {
        printf(errorString);
        printf("\n");
        dlclose(handle);
        return 1;
    }

    iPathEngine* pathEngine = (*PathEngine_InitialiseAndObtainRootInterface_Pointer)(&gErrorHandler);

    if(pathEngine->getInterfaceMajorVersion() != PATHENGINE_INTERFACE_MAJOR_VERSION
        ||
        pathEngine->getInterfaceMinorVersion() < PATHENGINE_INTERFACE_MINOR_VERSION)
    {
        gErrorHandler.handle("Fatal", "LoadPathEngine: pathengine version is incompatible with headers used for compilation.", 0);
        return false;
    }

// *** do things with the API here



    (*PathEngine_ShutDown_Pointer);

    int error = dlclose(handle);
    if(error)
    {
        printf("error from dclose()\n");
        return 1;
    }
    return 0;
}

In order to make these dll calls your application is likely to need an additional '-ldl' linker switch.
(This and other details for the exact setup to use for shared object linkage may of course vary slightly between different Linux distributions, and across other platforms where a GCC build setup is used.)

A simple example project

A simple example project is provided, in 'SDKRoot/samples/LinkageWithSharedObject.

This consists of a single source file (Main.cpp) plus a python script to build this.
(In case you don't have python installed, it's pretty straightforward to understand what is going on in the supplied script, and compile the code directly by hand.)

The example code requires you to copy the desired PathEngine shared object file into the current directory before it is run.
The following sequence of commands shows how to build and run the example, on the GCCx86 platform, assuming the release version of the shared object has already been built:

[samples]$ cd LinkageWithSharedObject/
    [LinkageWithSharedObject]$ python Build.py
    g++ -I ../../interface -o Main.o -c Main.cpp
    g++ -o LinkageWithSharedObject.exe -ldl Main.o
    [LinkageWithSharedObject]$ cp ../../build/Release_GCCx86/PathEngine/PathEngine.so .
    [LinkageWithSharedObject]$ ./LinkageWithSharedObject.exe
    Simple test completed successfully.
    [LinkageWithSharedObject]$

Memory instrumentation and shared object linkage

PathEngine's memory instrumentation uses a very simple technique based on over-riding global new and delete operators, and is designed for use with the DLL build of the SDK.
Depending on the options provided for control of symbol visibility by the linker on your target platform and the exact details for how these work with relation to global new and delete operators, it may or may not be possible to get this memory instrumentation working in shared object builds.


Documentation for PathEngine release 5.16 - Copyright © 2002-2008 PathEnginenext: Linking with PathEngine Statically