PathEngine home previous: Interface Version Numbersnext: Linking with the TestBed
Contents, Programmers Guide, Linking with the SDK, Linking with the PathEngine DLL

Linking with the PathEngine DLL

DLL linkage is recommended on platforms where this is supported.
On platforms where DLL style linkage is not supported shared object or static linkage can be used.
(See Dynamic Linking on GCC Based Platforms and Linking with PathEngine Statically for details.)

If you are used to static linkage, or DLL linkage with lib files, then the DLL linkage used for PathEngine may seem a little strange initially, but arranging the linkage in this way has the advantages of encapsulating each SDK release in a single file and ensuring clean and robust operation against changing versions of the SDK.
Explicit LoadLibrary() calls are preferred over lib files because this enables run-time reloading of the DLL and ensures that the client application has full control of the DLL location and loading process.

Obtaining an entry point

Note that the following instructions only apply to the full version of the SDK.
'TestBed only' versions of the SDK do not contain a standalone version of the PathEngine dll.

Use the Win32 function LoadLibrary() (or LoadLibraryEx()) to load pathengine.dll, and then the Win32 function GetProcAddress() to obtain a pointer to PathEngine's entrypoint.

After loading, the dll must be initialised, by calling DLLExport_Init, and then a root interface pointer can be obtained with DLLExport_CreateIPathEngine.

The following code snippet shows an example of this, and you can also refer to code for loading the DLL in the SDK examples (located at 'SDKRoot/code/sampleShared/LoadPathEngine.cpp' at the time of writing).

#include "loadpathengine.h"
#include <windows.h>
#include <stdio.h>

iPathEngine* LoadPathEngine(const char* fileName, iErrorHandler* handler)
{
    char buffer[500];
    DWORD errorValue;
    HINSTANCE hInstance;
    hInstance = LoadLibrary(fileName);
    if(!hInstance)
    {
        errorValue = GetLastError();
        MessageBox(NULL, fileName, "Error: failed calling LoadLibrary() for", MB_OK);
        sprintf(buffer, "%d", errorValue);
        MessageBox(NULL, buffer, "GetLastError()", MB_OK);
        return 0;
    }
    
    FARPROC procAddress;

    SetLastError(0);
    procAddress = GetProcAddress(hInstance, "DLLExport_Init");
    if(!procAddress)
    {
        errorValue = GetLastError();
        MessageBox(NULL, fileName, "Error: Failed to obtain entry point for DLLExport_Init in", MB_OK);
        sprintf(buffer, "%d", errorValue);
        MessageBox(NULL, buffer, "GetLastError()", MB_OK);
        return 0;
    }

    typedef void (__stdcall* tInitFunction)(iAllocator* allocator, iErrorHandler* handler); // ** note that __stdcall is ignored on x64

    tInitFunction initFunction = (tInitFunction)procAddress;
    initFunction(nullptr, handler);

    SetLastError(0);
    procAddress = GetProcAddress(hInstance, "DLLExport_CreateIPathEngine");
    if(!procAddress)
    {
        errorValue = GetLastError();
        MessageBox(NULL, fileName, "Error: Failed to obtain entry point for DLLExport_CreateIPathEngine in", MB_OK);
        sprintf(buffer, "%d", errorValue);
        MessageBox(NULL, buffer, "GetLastError()", MB_OK);
        return 0;
    }

    typedef iPathEngine* (__stdcall* tCreateFunction)(); // ** note that __stdcall is ignored on x64
    tCreateFunction getInterfaceFunction = (tCreateFunction)procAddress;
    return getInterfaceFunction();
}
	

Shared object linkage

On Linux, FreeBSD, and various other operating systems, the 'shared objects' mechanism provides run-time linkage that is similar in some ways to DLL linkage.


Documentation for PathEngine release 6.03 - Copyright © 2002-2021 PathEnginenext: Linking with the TestBed