00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00046 #include "PluginLoader.hpp"
00047 #include "../TaskContext.hpp"
00048 #include "../Logger.hpp"
00049 #include <boost/filesystem.hpp>
00050 #include <boost/version.hpp>
00051 #include "../os/StartStopManager.hpp"
00052 #include "../os/MutexLock.hpp"
00053 #include "../internal/GlobalService.hpp"
00054
00055 #include <cstdlib>
00056 #include <dlfcn.h>
00057
00058 #include <vector>
00059 #include <set>
00060
00061 using namespace RTT;
00062 using namespace RTT::detail;
00063 using namespace plugin;
00064 using namespace std;
00065 using namespace boost::filesystem;
00066
00067
00068 #ifdef __APPLE__
00069 static const std::string SO_EXT(".dylib");
00070 static const std::string SO_POSTFIX("");
00071 #else
00072 # ifdef _WIN32
00073 static const std::string SO_EXT(".dll");
00074 # ifdef _DEBUG
00075 static const std::string SO_POSTFIX("d");
00076 # else
00077 static const std::string SO_POSTFIX("");
00078 # endif // _DEBUG
00079 # else
00080 static const std::string SO_EXT(".so");
00081 static const std::string SO_POSTFIX("");
00082 # endif
00083 #endif
00084
00085
00086 static const std::string FULL_PLUGINS_SUFFIX(string("-") + string(OROCOS_TARGET_NAME) + SO_POSTFIX + SO_EXT);
00087
00088
00089 # ifdef _WIN32
00090 static const std::string delimiters(";");
00091 static const std::string default_delimiter(";");
00092 # else
00093 static const std::string delimiters(":;");
00094 static const std::string default_delimiter(":");
00095 # endif
00096
00097
00098 #ifndef RTT_UNUSED
00099 #ifdef __GNUC__
00100 #define RTT_UNUSED __attribute__((unused))
00101 #else
00102 #define RTT_UNUSED
00103 #endif
00104 #endif
00105
00114 RTT_API bool isExtensionVersion(const std::string& ext)
00115 {
00116 bool isExtensionVersion = false;
00117
00118 if (!ext.empty() && ('.' == ext[0]))
00119 {
00120 std::istringstream iss;
00121 int i;
00122
00123 iss.str(ext.substr((size_t)1));
00124 iss >> std::dec >> std::noskipws >> i;
00125 isExtensionVersion = !iss.fail() && iss.eof();
00126 }
00127
00128 return isExtensionVersion;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 RTT_API bool isLoadableLibrary(const path& filename)
00153 {
00154 bool isLoadable = false;
00155
00156 #if defined(__APPLE__)
00157 std::string ext;
00158 #if BOOST_VERSION >= 104600
00159 ext = filename.extension().string();
00160 #else
00161 ext = filename.extension();
00162 #endif
00163
00164 if (0 == ext.compare(SO_EXT))
00165 {
00166
00167
00168
00169 path name = filename.stem();
00170 path ext = name.extension();
00171 isLoadable =
00172
00173 !name.empty() &&
00174
00175 (ext.empty() || !isExtensionVersion(ext.string()));
00176 }
00177
00178
00179 #else
00180
00181
00182
00183 isLoadable =
00184 (filename.extension() == SO_EXT) &&
00185 !filename.stem().empty();
00186 #endif
00187
00188 return isLoadable;
00189 }
00190
00191 namespace {
00192
00193 static vector<string> splitPaths(string const& str)
00194 {
00195 vector<string> paths;
00196
00197
00198 string::size_type lastPos = str.find_first_not_of(delimiters, 0);
00199
00200 string::size_type pos = str.find_first_of(delimiters, lastPos);
00201
00202 while (string::npos != pos || string::npos != lastPos)
00203 {
00204
00205 if ( !str.substr(lastPos, pos - lastPos).empty() )
00206 paths.push_back(str.substr(lastPos, pos - lastPos));
00207
00208 lastPos = str.find_first_not_of(delimiters, pos);
00209
00210 pos = str.find_first_of(delimiters, lastPos);
00211 }
00212 if ( paths.empty() )
00213 paths.push_back(".");
00214 return paths;
00215 }
00216
00217 static void removeDuplicates(string& path_list)
00218 {
00219 vector<string> paths;
00220 set<string> seen;
00221 string result;
00222
00223
00224 paths = splitPaths( path_list );
00225
00226
00227 for(vector<string>::const_iterator it = paths.begin(); it != paths.end(); ++it)
00228 {
00229 if (seen.count(*it))
00230 continue;
00231 else
00232 seen.insert(*it);
00233
00234 result = result + *it + default_delimiter;
00235 }
00236
00237
00238 if (result.size() >= default_delimiter.size() && result.substr(result.size() - default_delimiter.size()) == default_delimiter)
00239 result = result.substr(0, result.size() - default_delimiter.size());
00240
00241 path_list.swap(result);
00242 }
00243
00250 static string makeShortFilename(string const& str) {
00251 string ret = str;
00252 if (str.substr(0,3) == "lib")
00253 ret = str.substr(3);
00254 if (ret.rfind(FULL_PLUGINS_SUFFIX) != string::npos)
00255 ret = ret.substr(0, ret.rfind(FULL_PLUGINS_SUFFIX) );
00256 return ret;
00257 }
00258
00259 }
00260
00261 static RTT_UNUSED bool hasEnding(string const &fullString, string const &ending)
00262 {
00263 if (fullString.length() > ending.length()) {
00264 return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
00265 } else {
00266 return false;
00267 }
00268 }
00269
00270 namespace RTT { namespace plugin {
00271 extern char const* default_plugin_path;
00272 }}
00273
00274 namespace {
00278 int loadPlugins()
00279 {
00280 std::string default_plugin_path = ::default_plugin_path;
00281
00282 char* paths = getenv("RTT_COMPONENT_PATH");
00283 string plugin_paths;
00284 if (paths) {
00285 plugin_paths = paths;
00286
00287 if ( !default_plugin_path.empty() )
00288 plugin_paths = plugin_paths + default_delimiter + default_plugin_path;
00289 removeDuplicates( plugin_paths );
00290 log(Info) <<"RTT_COMPONENT_PATH was set to: " << paths << " . Searching in: "<< plugin_paths<< endlog();
00291 } else {
00292 plugin_paths = default_plugin_path;
00293 removeDuplicates( plugin_paths );
00294 log(Info) <<"No RTT_COMPONENT_PATH set. Using default: " << plugin_paths <<endlog();
00295 }
00296
00297 PluginLoader::Instance()->setPluginPath(plugin_paths);
00298
00299 try {
00300 PluginLoader::Instance()->loadPlugin("rtt", plugin_paths);
00301 PluginLoader::Instance()->loadTypekit("rtt", plugin_paths);
00302 } catch(std::exception& e) {
00303 log(Warning) << e.what() <<endlog();
00304 log(Warning) << "Corrupted files found in '" << plugin_paths << "'. Fix or remove these plugins."<<endlog();
00305 }
00306 return 0;
00307 }
00308
00309 os::InitFunction plugin_loader( &loadPlugins );
00310
00311 void unloadPlugins()
00312 {
00313 PluginLoader::Release();
00314 }
00315
00316 os::CleanupFunction plugin_unloader( &unloadPlugins );
00317 }
00318
00319 static boost::shared_ptr<PluginLoader> instance2;
00320
00321 PluginLoader::PluginLoader() { log(Debug) <<"PluginLoader Created" <<endlog(); }
00322 PluginLoader::~PluginLoader(){ log(Debug) <<"PluginLoader Destroyed" <<endlog(); }
00323
00324
00325 boost::shared_ptr<PluginLoader> PluginLoader::Instance() {
00326 if (!instance2) {
00327 instance2.reset( new PluginLoader() );
00328 }
00329 return instance2;
00330 }
00331
00332 void PluginLoader::Release() {
00333 instance2.reset();
00334 }
00335
00336 bool PluginLoader::loadTypekits(string const& path_list) {
00337 MutexLock lock( listlock );
00338 return loadPluginsInternal( path_list, "types", "typekit");
00339 }
00340
00341 bool PluginLoader::loadTypekit(std::string const& name, std::string const& path_list) {
00342 MutexLock lock( listlock );
00343 return loadPluginInternal(name, path_list, "types", "typekit");
00344 }
00345
00346 bool PluginLoader::loadPlugin(std::string const& name, std::string const& path_list) {
00347 MutexLock lock( listlock );
00348 return loadPluginInternal(name, path_list, "plugins", "plugin");
00349 }
00350
00351 bool PluginLoader::loadPlugins(string const& path_list) {
00352 MutexLock lock( listlock );
00353 return loadPluginsInternal( path_list, "plugins", "plugin");
00354 }
00355
00356 bool PluginLoader::loadService(string const& servicename, TaskContext* tc) {
00357 MutexLock lock( listlock );
00358 for(vector<LoadedLib>::iterator it= loadedLibs.begin(); it != loadedLibs.end(); ++it) {
00359 if (it->filename == servicename || it->plugname == servicename || it->shortname == servicename) {
00360 if (tc) {
00361 log(Info) << "Loading Service or Plugin " << servicename << " in TaskContext " << tc->getName() <<endlog();
00362 try {
00363 return it->loadPlugin( tc );
00364 } catch(std::exception& e) {
00365 log(Error) << "Service or Plugin "<< servicename <<" threw an exception during loading in " << tc->getName() << endlog();
00366 log(Error) << "Exception: "<< e.what() << endlog();
00367 return false;
00368 } catch(...) {
00369 log(Error) << "Service or Plugin "<< servicename <<" threw an unknown exception during loading in " << tc->getName() << endlog();
00370 return false;
00371 }
00372 } else {
00373
00374 if (it->is_service)
00375 try {
00376 return internal::GlobalService::Instance()->addService( it->createService() );
00377 } catch(std::exception& e) {
00378 log(Error) << "Service "<< servicename <<" threw an exception during loading in global service." << endlog();
00379 log(Error) << "Exception: "<< e.what() << endlog();
00380 return false;
00381 } catch(...) {
00382 log(Error) << "Service "<< servicename <<" threw an unknown exception during loading in global service. " << endlog();
00383 return false;
00384 }
00385 log(Error) << "Plugin "<< servicename << " was found, but it's not a Service." <<endlog();
00386 }
00387 }
00388 }
00389 log(Error) << "No such service or plugin: '"<< servicename << "'"<< endlog();
00390 return false;
00391 }
00392
00393
00394 bool PluginLoader::loadPluginsInternal( std::string const& path_list, std::string const& subdir, std::string const& kind )
00395 {
00396
00397 path arg( path_list );
00398 if (is_regular_file(arg)) {
00399 #if BOOST_VERSION >= 104600
00400 if ( loadInProcess(arg.string(), makeShortFilename(arg.filename().string()), kind, true) == false)
00401 #else
00402 if ( loadInProcess(arg.string(), makeShortFilename(arg.filename()), kind, true) == false)
00403 #endif
00404 throw std::runtime_error("The plugin "+path_list+" was found but could not be loaded !");
00405 log(Warning) << "You supplied a filename to 'loadPlugins(path)' or 'loadTypekits(path)'."<< nlog();
00406 log(Warning) << "Please use 'loadLibrary(filename)' instead since the function you use will only scan directories in future releases."<<endlog();
00407 return true;
00408 }
00409
00410
00411 vector<string> paths;
00412 if (path_list.empty())
00413 return false;
00414 else
00415 paths = splitPaths( path_list );
00416
00417 bool all_good = true, found = false;
00418
00419 for (vector<string>::iterator it = paths.begin(); it != paths.end(); ++it)
00420 {
00421
00422 path p = path(*it) / subdir;
00423 if (is_directory(p))
00424 {
00425 log(Info) << "Loading "<<kind<<" libraries from directory " << p.string() << " ..."<<endlog();
00426 for (directory_iterator itr(p); itr != directory_iterator(); ++itr)
00427 {
00428 log(Debug) << "Scanning file " << itr->path().string() << " ...";
00429 if (is_regular_file(itr->status()) && isLoadableLibrary(itr->path()) ) {
00430 found = true;
00431 std::string libname;
00432 #if BOOST_VERSION >= 104600
00433 libname = itr->path().filename().string();
00434 #else
00435 libname = itr->path().filename();
00436 #endif
00437 if(!isCompatiblePlugin(libname))
00438 {
00439 log(Debug) << "not a compatible plugin: ignored."<<endlog();
00440 }
00441 else
00442 {
00443 found = true;
00444 all_good = loadInProcess( itr->path().string(), makeShortFilename(libname), kind, true) && all_good;
00445 }
00446 } else {
00447 if (!is_regular_file(itr->status()))
00448 log(Debug) << "not a regular file: ignored."<<endlog();
00449 else
00450 log(Debug) << "not a " + SO_EXT + " library: ignored."<<endlog();
00451 }
00452 }
00453 }
00454 else
00455 log(Debug) << "No such directory: " << p << endlog();
00456 }
00457 if (!all_good)
00458 throw std::runtime_error("Some found plugins could not be loaded !");
00459 return found;
00460 }
00461
00462 bool PluginLoader::loadLibrary( std::string const& name )
00463 {
00464
00465 path arg( name );
00466 if (is_regular_file(arg)) {
00467 #if BOOST_VERSION >= 104600
00468 string subdir = arg.parent_path().filename().string();
00469 #else
00470 string subdir = arg.parent_path().leaf();
00471 #endif
00472 string kind;
00473
00474 if (subdir == "types") kind = "typekit";
00475 if (subdir == "plugins") kind = "plugin";
00476 if ( !kind.empty() ) {
00477 #if BOOST_VERSION >= 104600
00478 string libname = arg.filename().string();
00479 #else
00480 string libname = arg.filename();
00481 #endif
00482 if(!isCompatiblePlugin(libname))
00483 {
00484 log(Error) << "The " << kind << " " << name << " was found but is incompatible." << endlog();
00485 return false;
00486 }
00487
00488 #if BOOST_VERSION >= 104600
00489 if ( loadInProcess(arg.string(), makeShortFilename(arg.filename().string()), kind, true) == false)
00490 #else
00491 if ( loadInProcess(arg.string(), makeShortFilename(arg.filename()), kind, true) == false)
00492 #endif
00493 throw std::runtime_error("The plugin "+name+" was found but could not be loaded !");
00494 return true;
00495 }
00496
00497 log(Error) << "refusing to load " << name << " as I could not autodetect its type (name=" << name << ", path=" << arg.string() << ", subdir=" << subdir << ")" << endlog();
00498
00499 return false;
00500 }
00501
00502
00503 if ( arg.is_complete() )
00504 return false;
00505
00506
00507 path dir = arg.parent_path();
00508 #if BOOST_VERSION >= 104600
00509 string file = arg.filename().string();
00510 #else
00511 string file = arg.filename();
00512 #endif
00513 vector<string> paths = splitPaths(plugin_path);
00514 vector<string> tryouts( paths.size() * 8 );
00515 tryouts.clear();
00516
00517
00518 string subdir = "plugins"; string kind = "plugin";
00519 while (true) {
00520 for (vector<string>::iterator it = paths.begin(); it != paths.end(); ++it)
00521 {
00522 path p = path(*it) / dir / subdir / (file + FULL_PLUGINS_SUFFIX);
00523 tryouts.push_back( p.string() );
00524 if (is_regular_file( p ) && loadInProcess( p.string(), name, kind, true ) )
00525 return true;
00526 p = path(*it) / dir / subdir / ("lib" + file + FULL_PLUGINS_SUFFIX);
00527 tryouts.push_back( p.string() );
00528 if (is_regular_file( p ) && loadInProcess( p.string(), name, kind, true ) )
00529 return true;
00530 p = path(*it) / OROCOS_TARGET_NAME / dir / subdir / (file + FULL_PLUGINS_SUFFIX);
00531 tryouts.push_back( p.string() );
00532 if (is_regular_file( p ) && loadInProcess( p.string(), name, kind, true ) )
00533 return true;
00534 p = path(*it) / OROCOS_TARGET_NAME / dir / subdir / ("lib" + file + FULL_PLUGINS_SUFFIX);
00535 tryouts.push_back( p.string() );
00536 if (is_regular_file( p ) && loadInProcess( p.string(), name, kind, true ) )
00537 return true;
00538 }
00539 if (subdir == "types")
00540 break;
00541 subdir = "types";
00542 kind = "typekit";
00543 }
00544 log(Debug) << "No such "<< kind << " found in path: " << name << ". Tried:"<< endlog();
00545 for(vector<string>::iterator it=tryouts.begin(); it != tryouts.end(); ++it)
00546 log(Debug) << *it << endlog();
00547
00548 return false;
00549 }
00550
00551 bool PluginLoader::loadPluginInternal( std::string const& name, std::string const& path_list, std::string const& subdir, std::string const& kind )
00552 {
00553
00554
00555 if (name != "rtt" && loadLibrary(name)) {
00556 log(Warning) << "You supplied a filename as first argument to 'loadPlugin(name,path)' or 'loadTypekit(name,path)'."<<nlog();
00557 log(Warning) << "Please use 'loadLibrary(filename)' instead since the function you use will only interprete 'name' as a directory name in future releases."<<endlog();
00558 return true;
00559 }
00560
00561 if ( isLoadedInternal(name) ) {
00562 log(Debug) <<kind << " '"<< name <<"' already loaded. Not reloading it." <<endlog();
00563 return true;
00564 } else {
00565 log(Info) << kind << " '"<< name <<"' not loaded before." <<endlog();
00566 }
00567
00568 string paths, trypaths;
00569 if (path_list.empty())
00570 paths = plugin_path + default_delimiter + ".";
00571 else
00572 paths = path_list;
00573
00574
00575 if (paths.empty())
00576 paths = ".";
00577
00578
00579 vector<string> vpaths = splitPaths(paths);
00580 paths.clear();
00581 bool path_found = false;
00582 string plugin_dir = name;
00583 if (name == "rtt" )
00584 plugin_dir = ".";
00585 for(vector<string>::iterator it = vpaths.begin(); it != vpaths.end(); ++it) {
00586 path p(*it);
00587 p = p / plugin_dir;
00588
00589 if (is_directory( p )) {
00590 path_found = true;
00591 paths += p.string() + default_delimiter;
00592 } else {
00593 trypaths += p.string() + default_delimiter;
00594 }
00595 p = *it;
00596 p = p / OROCOS_TARGET_NAME / plugin_dir;
00597
00598 if (is_directory( p )) {
00599 path_found = true;
00600 paths += p.string() + default_delimiter;
00601 } else {
00602 trypaths += p.string() + default_delimiter;
00603 }
00604 }
00605
00606
00607 if (path_found) {
00608 paths.erase( paths.size() - 1 );
00609 return loadPluginsInternal(paths,subdir,kind);
00610 }
00611 log(Error) << "No such "<< kind << " found in path: " << name << ". Looked for these directories: "<< endlog();
00612 if ( !paths.empty() )
00613 log(Error) << "Exist, but don't contain it: " << paths << endlog();
00614 else
00615 log(Error) << "None of the search paths exist !" << endlog();
00616 if ( !trypaths.empty() )
00617 log(Error) << "Don't exist: " << trypaths << endlog();
00618 return false;
00619 }
00620
00621 bool PluginLoader::isLoaded(string file)
00622 {
00623 MutexLock lock( listlock );
00624 return isLoadedInternal(file);
00625 }
00626
00627 bool PluginLoader::isLoadedInternal(string file)
00628 {
00629 path p(file);
00630 std::vector<LoadedLib>::iterator lib = loadedLibs.begin();
00631 while (lib != loadedLibs.end()) {
00632
00633 if ( lib->filename == p.filename() || lib->plugname == file || lib->shortname == file ) {
00634 return true;
00635 }
00636 ++lib;
00637 }
00638 return false;
00639 }
00640
00641
00642 bool PluginLoader::loadInProcess(string file, string shortname, string kind, bool log_error) {
00643 path p(file);
00644 char* error;
00645 void* handle;
00646
00647 if ( isLoadedInternal(shortname) || isLoadedInternal(file) ) {
00648 log(Debug) <<"plugin '"<< file <<"' already loaded. Not reloading it." <<endlog() ;
00649 return true;
00650 }
00651
00652
00653 if(!isCompatiblePlugin(file))
00654 {
00655 if(log_error)
00656 log(Error) << "could not load library '"<< p.string() <<"': incompatible." <<endlog();
00657 return false;
00658 }
00659
00660 handle = dlopen ( p.string().c_str(), RTLD_NOW | RTLD_GLOBAL );
00661
00662 if (!handle) {
00663 string e( dlerror() );
00664 if (log_error)
00665 log(Error) << "could not load library '"<< p.string() <<"': "<< e <<endlog();
00666 else
00667 endlog();
00668 return false;
00669 }
00670
00671
00672 #if BOOST_VERSION >= 104600
00673 string libname = p.filename().string();
00674 #else
00675 string libname = p.filename();
00676 #endif
00677 log(Debug)<<"Found library "<<libname<<endlog();
00678 LoadedLib loading_lib(libname,shortname,handle);
00679 dlerror();
00680
00681 std::string(*pluginName)(void) = 0;
00682 std::string(*targetName)(void) = 0;
00683 loading_lib.loadPlugin = (bool(*)(RTT::TaskContext*))(dlsym(handle, "loadRTTPlugin") );
00684 if ((error = dlerror()) == NULL) {
00685 string plugname, targetname;
00686 pluginName = (std::string(*)(void))(dlsym(handle, "getRTTPluginName") );
00687 if ((error = dlerror()) == NULL) {
00688 plugname = (*pluginName)();
00689 } else {
00690 plugname = libname;
00691 }
00692 loading_lib.plugname = plugname;
00693 targetName = (std::string(*)(void))(dlsym(handle, "getRTTTargetName") );
00694 if ((error = dlerror()) == NULL) {
00695 targetname = (*targetName)();
00696 } else {
00697 targetname = OROCOS_TARGET_NAME;
00698 }
00699 if ( targetname != OROCOS_TARGET_NAME ) {
00700 log(Error) << "Plugin "<< plugname <<" reports to be compiled for OROCOS_TARGET "<< targetname
00701 << " while we are running on target "<< OROCOS_TARGET_NAME <<". Unloading."<<endlog();
00702 dlclose(handle);
00703 return false;
00704 }
00705
00706
00707 loading_lib.createService = (Service::shared_ptr(*)(void))(dlsym(handle, "createService") );
00708 if (loading_lib.createService)
00709 loading_lib.is_service = true;
00710
00711
00712 bool success = false;
00713 try {
00714
00715 success = (*loading_lib.loadPlugin)( 0 );
00716 } catch(...) {
00717 log(Error) << "Unexpected exception in loadRTTPlugin !"<<endlog();
00718 }
00719
00720 if ( !success ) {
00721 log(Error) << "Failed to load RTT Plugin '" <<plugname<<"': plugin refused to load into this process. Unloading." <<endlog();
00722 dlclose(handle);
00723 return false;
00724 }
00725 if (kind == "typekit") {
00726 log(Info) << "Loaded RTT TypeKit/Transport '" + plugname + "' from '" + shortname +"'"<<endlog();
00727 loading_lib.is_typekit = true;
00728 } else {
00729 loading_lib.is_typekit = false;
00730 if ( loading_lib.is_service ) {
00731 log(Info) << "Loaded RTT Service '" + plugname + "' from '" + shortname +"'"<<endlog();
00732 }
00733 else {
00734 log(Info) << "Loaded RTT Plugin '" + plugname + "' from '" + shortname +"'"<<endlog();
00735 }
00736 }
00737 loadedLibs.push_back(loading_lib);
00738 return true;
00739 } else {
00740 if (log_error)
00741 log(Error) <<"Not a plugin: " << error << endlog();
00742 }
00743 dlclose(handle);
00744 return false;
00745 }
00746
00747 std::vector<std::string> PluginLoader::listServices() const {
00748 MutexLock lock( listlock );
00749 vector<string> names;
00750 for(vector<LoadedLib>::const_iterator it= loadedLibs.begin(); it != loadedLibs.end(); ++it) {
00751 if ( it->is_service )
00752 names.push_back( it->plugname );
00753 }
00754 return names;
00755 }
00756
00757 std::vector<std::string> PluginLoader::listPlugins() const {
00758 MutexLock lock( listlock );
00759 vector<string> names;
00760 for(vector<LoadedLib>::const_iterator it= loadedLibs.begin(); it != loadedLibs.end(); ++it) {
00761 names.push_back( it->plugname );
00762 }
00763 return names;
00764 }
00765
00766 std::vector<std::string> PluginLoader::listTypekits() const {
00767 MutexLock lock( listlock );
00768 vector<string> names;
00769 for(vector<LoadedLib>::const_iterator it= loadedLibs.begin(); it != loadedLibs.end(); ++it) {
00770 if ( it->is_typekit )
00771 names.push_back( it->plugname );
00772 }
00773 return names;
00774 }
00775
00776 std::string PluginLoader::getPluginPath() const {
00777 MutexLock lock( listlock );
00778 return plugin_path;
00779 }
00780
00781 void PluginLoader::setPluginPath( std::string const& newpath ) {
00782 MutexLock lock( listlock );
00783 plugin_path = newpath;
00784 }
00785
00786 bool PluginLoader::isCompatiblePlugin(std::string const& filepath)
00787 {
00788 path p(filepath);
00789
00790 #if BOOST_VERSION >= 104600
00791 string libname = p.filename().string();
00792 #else
00793 string libname = p.filename();
00794 #endif
00795
00796
00797
00798 #ifdef OROCOS_TARGET_WIN32
00799
00800
00801
00802 if(!hasEnding(libname, FULL_PLUGINS_SUFFIX))
00803 {
00804
00805 return false;
00806 }
00807 #endif // OROCOS_TARGET_WIN32
00808
00809
00810
00811
00812
00813 return true;
00814 }