The following code listing works just fine - but as I'm still dipping my toes into the C++ waters, I'm wondering if there is a better - more generic - way to define each of the function definitions.
I planning on using dynamic libraries as a sort of plugin system for a game, and am thinking of using something like a std::map<functionName, functionPtr> type of arrangement to keep track of each of the functions available for each plugin. But I don't know a way to implement that with how each of the function definitions is different.
#include <cassert>
#include <iostream>
#include <dlfcn.h>
//
// How could I encapsulate these in a consistent way?
//
typedef bool (*logfileOpen_type)(const std::string &newFileName); // logfile_open
typedef void (*logfileWrite_type)(const std::string &logText); //logfile_write
typedef void (*logfileClose_type)(); //logfile_close
typedef std::string (*logfileError_type)(); //logFile_getLastError
typedef bool (*logfileActive_type)(); //logFile_enabled
int main()
{
// Load a dynamic plugin.
auto libHandle = dlopen("./libPluginLogfile.so", RTLD_LAZY);
assert(libHandle != nullptr);
if (libHandle != nullptr)
printf("INFO: Plugin successfully loaded.\n");
else
{
printf("ERROR: Plugin failed to load.\n");
exit(-1);
}
// Get the address of the desired function
auto openFunction = (logfileOpen_type) dlsym(libHandle, "logFile_open");
if (openFunction == nullptr)
printf("Unable to find function [ %s ] [ %s ]\n", "logFile_open", dlerror());
auto writeFunction = (logfileWrite_type) dlsym(libHandle, "logFile_write");
if (writeFunction == nullptr)
printf("Unable to find function [ %s ] [ %s ]\n", "logFile_write", dlerror());
auto closeFunction = (logfileClose_type) dlsym(libHandle, "logFile_close");
if (closeFunction == nullptr)
printf("Unable to find function [ %s ] [ %s ]\n", "logFile_close", dlerror());
auto getErrorFunction = (logfileError_type) dlsym(libHandle, "logFile_getLastError");
if (getErrorFunction == nullptr)
printf("Unable to find function [ %s ] [ %s ]\n", "logFile_getLastError", dlerror());
auto getEnabledFunction = (logfileActive_type) dlsym(libHandle, "logFile_enabled");
if (getEnabledFunction == nullptr)
printf("Unable to find function [ %s ] [ %s ]\n", "logFile_enabled", dlerror());
openFunction("logfile.log");
writeFunction("Writing to the logfile.");
writeFunction(".. and a second line.");
closeFunction();
dlclose(libHandle);
std::cout << "INFO: Plugin Unloaded." << std::endl;
return 0;
}
The code works fine - but is there a better way?
As I understand it, if you just want to index function names to function pointers using a map-like method, you can cast all function pointers to const void*. The caller of the function is responsible for reverting it back to the correct function signature. After all, the caller is obligated to know the true signature of the function by, for example, consulting the documentation.