+ bbtkDebugMessage("package",3," ... Package has been released"
+ <<std::endl);
+ }
+ */
+ }
+ //==========================================================================
+
+ //==========================================================================
+ /// Opens a dynamic library which contains a bbtk package
+ /// Returns the handler
+ /// Load the package management symbols from the lib
+ /// returns false if a problem occured hence can be used
+ /// to test that a dyn lib is a valid bbtk package lib
+ /// NB : The BBTK version exported from the library
+ /// is tested against the current bbtk version
+ DynamicLibraryHandler Package::OpenDynamicLibrary
+ ( const std::string& libname,
+ const std::string& package_name,
+ DLGetPackageFunction& getpack,
+ DLDeletePackageFunction& delpack)
+ {
+ bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
+ <<libname<<")"<<std::endl);
+#if defined(__GNUC__)
+
+ // Open shared lib
+ void *handler;
+ handler = dlopen(libname.c_str(),
+ BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
+ if (!handler)
+ {
+ bbtkMessage("package",2,
+ "Could not open shared library [" <<libname<<"] : "
+ <<dlerror() << std::endl);
+ return 0;
+ }
+
+ bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
+
+ // Loads the Package bbtk version function
+ std::string getvername(package_name);
+ getvername +=
+ BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
+ DLGetPackageBBTKVersionFunction getbbtkversion
+ = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
+ if (!getbbtkversion)
+ {
+ bbtkDebugMessage("package",3,"***"<<std::endl);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
+ dlclose(handler);
+ return 0;
+ }
+
+ bbtkDebugMessage("package",3,"* Symbol ["<<getvername
+ <<"] found"<<std::endl);
+ // version matches ?
+ if (getbbtkversion() != bbtk::GetVersion())
+ {
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] was build with bbtk version "
+ <<getbbtkversion()
+ <<" but the current program runs with version "
+ <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
+ dlclose(handler);
+ return 0;
+
+ }
+
+ bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
+ // Loads the Package get function
+ std::string getpackname(package_name);
+ getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
+ getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
+ if (!getpack)
+ {
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
+ dlclose(handler);
+ return 0;
+ }
+
+ bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
+ // Loads the Package delete function
+
+ std::string delpackname(package_name);
+ delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
+ delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
+ if (!delpack)
+ {
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
+ dlclose(handler);
+ return 0;
+ }
+ bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);
+#elif defined(_WIN32)
+
+ HINSTANCE handler;
+
+ SetErrorMode(0);
+ // Open shared lib
+ handler = LoadLibrary(libname.c_str());
+ if (!handler)
+ {
+ bbtkMessage("package",2,
+ "Could not open shared library [" <<libname<<"]"
+ << std::endl);
+ DWORD dwErrorCode = 0;
+ dwErrorCode = GetLastError();
+ bbtkMessage("package",2,
+ "Windows Error: [" << dwErrorCode <<"]"
+ << std::endl);
+
+ return 0;
+ }
+
+ // Loads the Package bbtk version function
+ std::string getvername(package_name);
+ getvername +=
+ BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
+ DLGetPackageBBTKVersionFunction getbbtkversion
+ = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler,
+ getvername.c_str()));
+ if (!getbbtkversion)
+ {
+ FreeLibrary(handler);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
+ return 0;
+ }
+
+ // version matches ?
+ if (getbbtkversion() != bbtk::GetVersion())
+ {
+ FreeLibrary(handler);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] was build with bbtk version "
+ <<getbbtkversion()
+ <<" but the current program runs with version "
+ <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
+ return 0;
+
+ }
+
+ // Loads the Package get function
+ std::string getpackname(package_name);
+ getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
+ getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
+ if (!getpack)
+ {
+ FreeLibrary(handler);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
+ return 0;
+ }
+
+ // Loads the Package delete function
+ std::string delpackname(package_name);
+ delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
+ delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
+ if (!delpack)
+ {
+ FreeLibrary(handler);
+ bbtkMessage("package",2,
+ "Shared library ["<<libname
+ <<"] is not a valid bbtk package."
+ <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
+ return 0;
+ }
+
+#else
+ bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
+#endif
+
+ return handler;
+ }
+ //==========================================================================
+
+ //==========================================================================
+ /// Loads a package from a dynamic library
+ Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
+ const std::string& pkgname,
+ const std::string& path)
+ {
+ bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
+ <<libname<<")"<<std::endl);
+
+ DLGetPackageFunction gf;
+ DLDeletePackageFunction df;
+ DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
+ pkgname,
+ gf,df);
+ if (h==0) return Package::Pointer();
+ Package::Pointer p = gf();
+ p->mDynamicLibraryHandler = h;
+ p->mDLDeletePackageFunction = df;
+
+ std::string separator =
+ ConfigurationFile::GetInstance().Get_file_separator ();
+ //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
+ std::string docreldoc =
+ separator + "bbdoc" + separator + pkgname + separator + "index.html";
+ std::string reldoc =
+ ".." + separator + ".." + docreldoc;
+ std::string doc = path + separator + ".." + separator
+ + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
+ + docreldoc;
+
+ p->SetDocURL(doc);
+ p->SetDocRelativeURL(reldoc);
+
+ bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
+ <<libname<<") .. OK"<<std::endl);
+ return p;
+ }
+ //==========================================================================
+
+
+
+
+ //==========================================================================
+ /// UnLoads the package dynamic library (if any)
+ void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
+ {
+ if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
+ return;
+
+
+ std::string packname = pack.lock()->GetName();
+ bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
+ <<packname<<"')"
+ <<std::endl);
+
+ if (!pack.lock()->GetBlackBoxMap().empty())
+ {
+
+ bbtkDebugMessage("package",5," Package not empty ... abort"
+ <<std::endl);
+ return;
+ /*
+ bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
+ <<"BlackBoxMap not empty "
+ <<BBTK_INTERNAL_ERROR_MESSAGE);
+ */
+
+ }
+
+ if (pack.use_count()!=1)
+ {
+ bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
+ <<"empty dl package with external refs"
+ <<BBTK_INTERNAL_ERROR_MESSAGE);
+ }
+
+ if (doit)
+ {
+ UnLoad(pack);
+ bbtkDebugMessage("package",5,"==> dynamic library for package '"
+ <<packname<<"' closed"
+ <<std::endl);
+ }
+ else
+ {
+ mReleasedDynamicallyLoadedPackages.insert(pack);
+ bbtkDebugMessage("package",1,"==> package '"<<packname
+ <<"' put in the 'to unload' list"
+ <<std::endl);
+
+ }
+
+ bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
+ <<packname<<"')"
+ <<std::endl);
+
+ }
+ //==========================================================================
+
+ //==========================================================================
+ /// UnLoads released packages that were loaded dynamically
+ /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
+ void Package::UnLoadReleasedDynamicallyLoadedPackages()
+ {
+ bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
+
+ std::set<Package::WeakPointer>::iterator i;
+
+//JCP- 21-04-09
+ if(mReleasedDynamicallyLoadedPackages.size()>0){
+ for (i=mReleasedDynamicallyLoadedPackages.begin();
+ i!=mReleasedDynamicallyLoadedPackages.end();
+ ++i)
+ {
+ if (!i->expired()) UnLoad(*i);
+ }