+ /// 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 );
+//EED handler = dlopen(libname.c_str(), RTLD_LAZY | RTLD_LOCAL );
+
+ 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;
+ }
+ //==========================================================================
+