/////////////////////////////////////////////////////////////////////////////// // loads a gls extension. #TODO: Robust name to path resolution. GLS_EXTENSION_MODULE *gls::gls_extension_load ( const char *name, unsigned long req_options, ExtensionHost *pHost ) { // validate name size_t lenName = strlen(name); if (lenName == 0 || lenName > GLS_EXTENSION_MAX_PATH_LEN) { return NULL; } // make lib path; keep enough space for path expanding { // char libPath [GLS_EXTENSION_MAX_LIB_NAME_LEN + 50]; char libPath [MAX_PATH]; #ifdef GLS_EXTENSION_LOAD_TREAT_NAME_AS_PATH strcpy (libPath, name); #else sprintf (libPath, "extensions\\%s%s.%s", EXT_MOD_NAME_PREFIX, name, EXT_MOD_EXT_NAME ); #endif // } make lib path // load the extension module #ifdef WIN32 HMODULE hExtMod = EXT_LOAD(libPath); #else void *hExtMod = NULL; #endif if (hExtMod == NULL) { return NULL; // failed to load the module } // get extension module entry points pfn_gls_extension_initialize pfn_ext_init; pfn_gls_extension_terminate pfn_ext_term; pfn_gls_extension_get_interface pfn_ext_get_int; EXT_ENTRY_POINT (hExtMod, pfn_ext_init, gls_extension_initialize); EXT_ENTRY_POINT (hExtMod, pfn_ext_term, gls_extension_terminate); EXT_ENTRY_POINT (hExtMod, pfn_ext_get_int, gls_extension_get_interface); // check for missing exports if (!pfn_ext_init || !pfn_ext_term || !pfn_ext_get_int) { EXT_UNLOAD(hExtMod); return NULL; } // try to initialize the extension if (!pfn_ext_init (pHost)) { EXT_UNLOAD(hExtMod); return NULL; // failed to initialize the extension } // get the extension interface and query extension capabilities Extension *pExtension = pfn_ext_get_int (); if (pExtension == NULL) { EXT_UNLOAD(hExtMod); return NULL; } // get extension's interface version unsigned short ext_int_ver = pExtension->GetInterfaceVersion (); unsigned char ext_int_ver_maj, ext_int_ver_min; ext_int_ver_maj = GLS_VERSION_GET_MAJOR(ext_int_ver); ext_int_ver_min = GLS_VERSION_GET_MINOR(ext_int_ver); // check for minimum interface version; extension's interface version // must be atleast equal to the required interface version unsigned char req_int_ver_maj, req_int_ver_min; req_int_ver_maj = 0; req_int_ver_min = 1; if ( (ext_int_ver_maj < req_int_ver_maj) || (ext_int_ver_maj == req_int_ver_maj && ext_int_ver_min < req_int_ver_min) ) { EXT_UNLOAD(hExtMod); // extension interface version is lower than required return NULL; } // query extension capabilities unsigned long capabilities = pExtension->GetCapabilities (); if ( (capabilities & req_options) != req_options ) { EXT_UNLOAD(hExtMod); // one or more capability not supported return NULL; } // query lib features GLS_EXTENSION_LIB_INFO libInfo; void *pLibInterface; if (req_options & GLS_EXTENSION_LIBRARY) { pExtension->GetLibInfo (&libInfo); pLibInterface = pExtension->GetLibInterface (); if (pLibInterface == NULL) { EXT_UNLOAD(hExtMod); // library interface not returned return NULL; } } // alloc a new extension module instance and return it GLS_EXTENSION_MODULE *pExtMod = new GLS_EXTENSION_MODULE (); memset (pExtMod, 0, sizeof(GLS_EXTENSION_MODULE)); strcpy ( pExtMod->path, name ); pExtMod->interfaceVersion = ext_int_ver; pExtMod->capabilities = capabilities; pExtMod->hModule = (void *)hExtMod; pExtMod->pExtInterface = pExtension; if (req_options & GLS_EXTENSION_LIBRARY) { memcpy (&pExtMod->libInfo, &libInfo, sizeof(GLS_EXTENSION_LIB_INFO)); // pExtMod->pLibInterface = reinterpret_cast<_GLScriptExtLib *> (pLibInterface); pExtMod->pLibInterface = pLibInterface; } return pExtMod; }