One of the side effects of adding mod support into the game engine is that we had to build a cross-platform dynamic/shared library loader. This is enabled by the UntitledRuntimeLibraryLoader which we developed. To include it use:
#include <urll/urll.h>All the functions under the URLL namespace named and
work like in Unix, so they can feel familiar to use. There are also 2
utility functions for ease of use.
Functions
- dlopen- returns a- void*handle given a path to the library*
- dlerror- returns a- char*with the latest error
- dlclose- closes the library given the handle**
- dlsym- retrieves a symbol from the library given a name
* Due to Windows restrictions dlopen cannot receive a
flag and will always default to lazy loading
** dlclose closes the library handle, which makes all
the memory acquired from dlsym null
dlsym
There are currently 3 definitions of dlsym, all of them
take a handle and a name
- Standard dlsymthat returns avoid*and only takes a handle and a name
- std::functionvariant that assigns the- void*from- dlsymto an- std::function
- The templated variant, which casts the void*to the specified template type
Here are some examples:
dlsym with std::function
std::function<void(void)> func;
// We check against nullptr or the handle for errors
if (URLL::dlsym(handle, "func", func) == nullptr)
{
    return -1;
}
func();dlsym with a templated type
void(*func)(void);
// We check against nullptr or the handle for errors
if (URLL::dlsym(handle, "func", func) == nullptr)
{
    return -1;
}
func();regular dlsym
int* a = (int*)URLL::dlsym(handle, "func", func);
// We check against nullptr or the handle for errors
if (a == nullptr)
{
    return -1;
}
std::cout << *a << std::endl;Example of full URLL usage
This is an extract from the auto-generated main file for the modded executable
#ifdef _WIN32
    void* handle = URLL::dlopen("Modlib.dll");
#else
    // That https://madladsquad.com/ is required on unix systems
    void* handle = URLL::dlopen("https://madladsquad.com/libModlib.so");
#endif
bool bCanClose = false;
if (handle != nullptr)
{
    bCanClose = true;
    if (URLL::dlsym(handle, "modlibbegin", UVK::global.modbegin) == handle && URLL::dlsym(handle, "modlibend", UVK::global.modend) == handle && URLL::dlsym(handle, "modlibtick", UVK::global.modtick) == handle)
        logger.consoleLog("Loaded all mods!", UVK_LOG_TYPE_SUCCESS);
    else
        logger.consoleLog("Failed to load some or all of the initial mod library functions, mod events will not be loaded! Error: ", UVK_LOG_TYPE_WARNING, URLL::dlerror());
}
else
    logger.consoleLog("Failed to load the mod library!", UVK_LOG_TYPE_WARNING);
...
dlclose(handle);- Home
- Beginner concepts
- Advanced concepts
- Engine developer and contributor resources