82 lines
No EOL
1.6 KiB
C++
82 lines
No EOL
1.6 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
|
|
#if defined(LINUX) || defined(EMSCRIPTEN)
|
|
#include <dlfcn.h>
|
|
#define EXPORT virtual
|
|
#define LIBRARY_SUFFIX ".so"
|
|
#define HANDLE_TYPE void*
|
|
#endif
|
|
|
|
#if WINDOWS
|
|
#define NOMINMAX
|
|
#define NOGDI
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#define EXPORT virtual __declspec(dllexport)
|
|
#define LIBRARY_SUFFIX ".dll"
|
|
#define HANDLE_TYPE HMODULE
|
|
#endif
|
|
|
|
#define FACTORY(x) extern "C" x* create_object() { return new x; }
|
|
|
|
#include <iostream>
|
|
|
|
template<class T>
|
|
class Module
|
|
{
|
|
public:
|
|
Module(const std::string& path)
|
|
{
|
|
#ifdef LINUX
|
|
handle = dlopen((path + LIBRARY_SUFFIX).c_str(), RTLD_LAZY);
|
|
if(!handle)
|
|
{
|
|
std::cerr << dlerror() << std::endl;
|
|
return;
|
|
}
|
|
|
|
create = reinterpret_cast<T* (*)()>(dlsym(handle, "create_object"));
|
|
const char* err = dlerror();
|
|
if(err)
|
|
{
|
|
std::cerr << err << std::endl;
|
|
return;
|
|
}
|
|
#endif
|
|
#if WINDOWS
|
|
handle = LoadLibrary((path + LIBRARY_SUFFIX).c_str());
|
|
if(!handle)
|
|
{
|
|
std::cerr << "Failed to load library " << path + LIBRARY_SUFFIX << std::endl;
|
|
}
|
|
create = reinterpret_cast<T* (*)()>(GetProcAddress(handle, "create_object"));
|
|
#endif
|
|
}
|
|
~Module()
|
|
{
|
|
#ifdef LINUX
|
|
if(handle && create)
|
|
dlclose(handle);
|
|
#endif
|
|
#ifdef WINDOWS
|
|
if(handle && create)
|
|
FreeLibrary(handle);
|
|
#endif
|
|
}
|
|
|
|
bool IsValid()
|
|
{
|
|
return handle != nullptr;
|
|
}
|
|
|
|
T* construct()
|
|
{
|
|
return create();
|
|
}
|
|
|
|
private:
|
|
T* (*create)();
|
|
HANDLE_TYPE handle = nullptr;
|
|
}; |