22 #ifndef CRNModule_HEADER
23 #define CRNModule_HEADER
38 inline HMODULE dlopen(
const char *P,
int G)
40 return LoadLibrary(P);
42 # define dlsym(D,F) (void*)GetProcAddress((HMODULE)D,F)
43 # define dlclose(D) FreeLibrary((HMODULE)D)
44 inline const char* dlerror()
46 static char szMsgBuf[256];
47 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
50 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
58 # define RTLD_GLOBAL 4
99 if (filename.SubString(filename.Size() - ext.Size()) != ext)
104 void *handle = dlopen(filename.CStr(), RTLD_NOW | RTLD_GLOBAL);
107 handles.push_back(handle);
108 Category* (*handleget)(void);
109 handleget = (Category* (*)(void))dlsym(handle, Category::GetModuleEntryPoint());
117 CRNDebug(
String(U
"int module::LoadDirectory(const String &dirname): Cannot find entry point in file ") + filename +
String(U
" (") + dlerror() +
String(U
")"));
122 CRNError(
String(U
"int module::LoadDirectory(const String &dirname): Cannot open file ") + filename +
String(U
" (") + dlerror() +
String(U
")"));
129 CRNError(
crn::String(U
"int module::LoadDirectory(const String &dirname): Cannot open directory ") + dirname);
145 CRNError(
String(U
"bool ModuleManager::RegisterModule(Category *mod): The module is of wrong category."));
150 modules.push_back(mod);
161 for (
void *h : handles)
167 std::vector<void*> handles;
168 std::vector<std::shared_ptr<Category> > modules;
177 #define CRN_MODULE_ENTRY_POINT(category) crn_module_get_##category
182 #define CRN_MODULE_ENTRY_POINT_AS_STRING(category) "crn_module_get_"#category
192 #define CRN_DECLARE_MODULE(categoryname) public: static const char* GetModuleEntryPoint() { return CRN_MODULE_ENTRY_POINT_AS_STRING(categoryname); }
212 #define CRN_BEGIN_MODULE(classname, categoryname) class classname: public categoryname {
232 #define CRN_END_MODULE(classname, categoryname) }; extern "C" categoryname* CRN_MODULE_ENTRY_POINT(categoryname)() { return new classname; }
int LoadDirectory(const Path &dirname, const String &ext=U"")
Loads modules contained in a directory.
bool RegisterModule(std::shared_ptr< Category > mod)
Registers a new module. DO NOT USE THIS METHOD DIRECTLY. Call CRN_BEGIN/END_MODULE.
~ModuleManager()
Destructor frees handles.
A handler to the content of a directory.
A UTF32 character string class.
ModuleManager()
Default constructor.
A convenience class for file paths.
A dynamic module manager.
const std::vector< Path > & GetFiles() const
Returns the list of files.
std::vector< std::shared_ptr< Category > > GetModules() const
Retrieves the modules that implement a given interface.