/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ /* rcg10072001 Implemented. */ #include #include #include class CUnixDynamicLoader : public CDynamicLoader { public: CUnixDynamicLoader(const char *libname); virtual ~CUnixDynamicLoader(void); virtual void *FindSymbol(const char *sym); virtual const char *GetError(void); protected: void DoOpen(const char *lib); void SetError(void); void *module; CTString *err; }; CDynamicLoader *CDynamicLoader::GetInstance(const char *libname) { return(new CUnixDynamicLoader(libname)); } void CUnixDynamicLoader::SetError(void) { const char *errmsg = ::dlerror(); delete err; err = NULL; if (errmsg != NULL) { CPrintF("CUnixDynamicLoader error: %s\n", errmsg); err = new CTString(errmsg); } } const char *CUnixDynamicLoader::GetError(void) { return((err) ? (const char *) (*err) : NULL); } void *CUnixDynamicLoader::FindSymbol(const char *sym) { //printf("Looking for symbol %s\n", sym); void *retval = NULL; if (module != NULL) { retval = ::dlsym(module, sym); SetError(); } return(retval); } void CUnixDynamicLoader::DoOpen(const char *lib) { module = ::dlopen(lib, RTLD_LAZY | RTLD_GLOBAL); SetError(); } CTFileName CDynamicLoader::ConvertLibNameToPlatform(const char *libname) { #if PLATFORM_MACOSX const char *DLLEXTSTR = ".dylib"; #else const char *DLLEXTSTR = ".so"; #endif CTFileName fnm = CTString(libname); CTString libstr((strncmp("lib", fnm.FileName(), 3) == 0) ? "" : "lib"); return(fnm.FileDir() + libstr + fnm.FileName() + DLLEXTSTR); } CUnixDynamicLoader::CUnixDynamicLoader(const char *libname) : module(NULL), err(NULL) { if (libname == NULL) { DoOpen(NULL); } else { CTFileName fnm = ConvertLibNameToPlatform(libname); // Always try to dlopen from inside the game dirs before trying // system libraries... if (fnm.FileDir() == "") { char buf[MAX_PATH]; _pFileSystem->GetExecutablePath(buf, sizeof (buf)); CTFileName fnmDir = CTString(buf); fnmDir = fnmDir.FileDir() + fnm; DoOpen(fnmDir); if (module != NULL) { return; } } DoOpen(fnm); } } CUnixDynamicLoader::~CUnixDynamicLoader(void) { delete err; if (module != NULL) ::dlclose(module); } // end of UnixDynamicLoader.cpp ...