#ifndef _AddOn_AddOnLoader_h_ #define _AddOn_AddOnLoader_h_ #include using namespace Upp; #include #ifdef PLATFORM_POSIX #include #endif template class AddOnLoader { public: AddOnLoader(){}; ~AddOnLoader(); int LoadFile(String name); int LoadFolder(String name); int GetCount(); T* At(int idx); T* operator[](int idx) {return At(idx);} private: AddOnLoader(const AddOnLoader&); bool Load(String name); struct Item { DLLHANDLE hmod; T* address; }; Array addOns; typedef IAddOn*(*Start)(); typedef void(*Stop)(); #if defined PLATFORM_WIN32 typedef HMODULE DLLHANDLE; #else typedef void* DLLHANDLE; #endif static const String sharedLibExt; }; #if defined PLATFORM_WIN32 || defined PLATFORM_WINCE template const String AddOnLoader::sharedLibExt = ".dll"; #elif defined PLATFORM_LINUX || defined PLATFORM_FREEBSD || defined PLATFORM_SOLARIS template const String AddOnLoader::sharedLibExt = ".so"; #elif defined PLATFORM_OSX11 template const String AddOnLoader::sharedLibExt = ".dylib"; #endif template AddOnLoader::~AddOnLoader() { for (int i = 0; i < addOns.GetCount(); i++) { #if defined PLATFORM_WIN32 || defined PLATFORM_WINCE Stop stop = (Stop)GetProcAddress(addOns[i].hmod, "Stop"); #else Stop stop = (Stop)dlsym(addOns[i].hmod, "Stop"); #endif if (stop) { stop(); } #if defined PLATFORM_WIN32 || defined PLATFORM_WINCE FreeLibrary(addOns[i].hmod); #else dlclose(addOns[i].hmod); #endif } addOns.Clear(); } template int AddOnLoader::LoadFile(String name) { if (FileExists(name)) { return Load(name)?1:0; } else { return 0; } } template int AddOnLoader::LoadFolder(String name) { int num = 0; for(FindFile ff(AppendFileName(name, "*.*")); ff; ff.Next()) { if (ff.IsFolder()) { num += LoadFolder(AppendFileName(name, ff.GetName())); } else if (ff.IsFile() && ToLower(GetFileExt(ff.GetName()) == sharedLibExt)) { num += Load(AppendFileName(name, ff.GetName())); } } return num; } template bool AddOnLoader::Load(String name) { bool status = false; #if defined PLATFORM_WIN32 || defined PLATFORM_WINCE DLLHANDLE hmod = LoadLibrary(NormalizePath(name)); #else DLLHANDLE hmod = dlopen(NormalizePath(name), RTLD_LAZY); #endif if (hmod) { #if defined PLATFORM_WIN32 || defined PLATFORM_WINCE Start start = (Start)GetProcAddress(hmod, "Start"); #else Start start = (Start)dlsym(hmod, "Start"); #endif T* plugin; if (start && (plugin = dynamic_cast(start()))) { Item& addOn = addOns.Add(); addOn.hmod = hmod; addOn.address = plugin; status = true; } else { #if defined PLATFORM_WIN32 || defined PLATFORM_WINCE FreeLibrary(hmod); #else dlclose(hmod); #endif } } return status; } template int AddOnLoader::GetCount() { return addOns.GetCount(); } template T* AddOnLoader::At(int idx) { if (idx < addOns.GetCount()) { return addOns[idx].address; } else { return NULL; } } #endif