From: stephan b. <sg...@us...> - 2004-12-23 21:08:18
|
Update of /cvsroot/pclasses/pclasses2/src/System In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6937 Added Files: SharedLib.ltdl.cpp Log Message: egg --- NEW FILE: SharedLib.ltdl.cpp --- /*************************************************************************** * Copyright (C) 2004 by Christian Prochnow * * cp...@se... * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Library General Public License as * * published by the Free Software Foundation; either version 2 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "pclasses/System/SharedLib.h" #include "pclasses/Phoenix.h" #include <ltdl.h> #include <errno.h> #ifndef PCLASSES_WITH_STL # error "This header requires PCLASSES_WITH_STL to be defined." #endif #include <string> #include <sstream> #include <map> #include <utility> // make_pair() namespace P { namespace System { typedef unsigned long handle_type; typedef std::map<handle_type,lt_dlhandle> lt_handle_map_t; struct ltdl_sharing_context {}; // marker class lt_handle_map_t & lt_handle_map() { typedef ::P::Phoenix< lt_handle_map_t, ltdl_sharing_context > PHX; return PHX::instance(); } int BindMode2Flags(SharedLib::BindMode mode) { // ltdl doesn't use dlopen() flags return 0; } SharedLib::SharedLib(const Unicode::String& name, BindMode mode) throw(SystemError) : _handle(0) { Unicode::String realName = name; realName.append(".so"); //@fixme _handle = (unsigned long)dlopen(realName.utf8(), BindMode2Flags(mode)); if(!_handle) throw SystemError(errno, lt_dlerror(), P_SOURCEINFO); } #ifdef PCLASSES_WITH_STL SharedLib::SharedLib(const std::string& name, BindMode mode) throw(SystemError) : _handle(0) { std::ostringstream realName; realName << name; realName << ".so"; lt_dlhandle h = lt_dlopen(realName.str().c_str() /** BindMode2Flags(mode) */ ); if( h ) { _handle = reinterpret_cast<handle_type>( static_cast<void *>( h ) ); lt_handle_map().insert( std::make_pair( _handle, h ) ); } if(!_handle) throw SystemError(errno, lt_dlerror(), P_SOURCEINFO); } #endif SharedLib::~SharedLib() throw() { lt_handle_map_t::iterator it = lt_handle_map().find( _handle ); if( lt_handle_map().end() != it ) { // nononono! // lt_dlclose((*it).second); lt_handle_map().erase( it ); } } void* SharedLib::operator[](const char* symbol) throw(RuntimeError) { lt_handle_map_t::iterator it = lt_handle_map().find( _handle ); if( lt_handle_map().end() == it ) { throw RuntimeError( "DLL handle is invalid.", P_SOURCEINFO ); } lt_dlhandle lth = (*it).second; void* addr = lt_dlsym( lth, symbol); if(!addr) { std::ostringstream os; os << "Symbol '"<<symbol<<"' not found in shared library."; throw RuntimeError(os.str().c_str(), P_SOURCEINFO); } return addr; } #ifdef PCLASSES_WITH_STL void* SharedLib::operator[](const std::string& symbol) throw(RuntimeError) { return operator[](symbol.c_str()); } #endif } // !namespace System } // !namespace P |