2003-01-22 00:45:36 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
|
|
|
|
*
|
|
|
|
* This library is open source and may be redistributed and/or modified under
|
|
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
2002-01-04 05:34:57 +08:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
2001-09-20 05:08:56 +08:00
|
|
|
#include <Io.h>
|
|
|
|
#include <Windows.h>
|
|
|
|
#include <Winbase.h>
|
2002-07-17 03:21:31 +08:00
|
|
|
#elif defined(__DARWIN_OSX__)
|
|
|
|
#include <mach-o/dyld.h>
|
|
|
|
#else // all other unix
|
2001-09-20 05:08:56 +08:00
|
|
|
#include <unistd.h>
|
2002-07-23 18:48:22 +08:00
|
|
|
#ifdef __hpux__
|
|
|
|
// Although HP-UX has dlopen() it is broken! We therefore need to stick
|
|
|
|
// to shl_load()/shl_unload()/shl_findsym()
|
|
|
|
#include <dl.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#else
|
2001-09-20 05:08:56 +08:00
|
|
|
#include <dlfcn.h>
|
|
|
|
#endif
|
2002-07-23 18:48:22 +08:00
|
|
|
#endif
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2001-10-22 05:27:40 +08:00
|
|
|
#include <osg/Notify>
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2001-10-22 05:27:40 +08:00
|
|
|
#include <osgDB/DynamicLibrary>
|
|
|
|
#include <osgDB/FileUtils>
|
2003-11-06 12:08:53 +08:00
|
|
|
#include <osgDB/FileNameUtils>
|
2001-09-20 05:08:56 +08:00
|
|
|
|
|
|
|
using namespace osg;
|
|
|
|
using namespace osgDB;
|
|
|
|
|
|
|
|
DynamicLibrary::DynamicLibrary(const std::string& name,HANDLE handle)
|
|
|
|
{
|
|
|
|
_name = name;
|
|
|
|
_handle = handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
DynamicLibrary::~DynamicLibrary()
|
|
|
|
{
|
|
|
|
if (_handle)
|
|
|
|
{
|
2002-01-04 05:34:57 +08:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
2001-09-20 05:08:56 +08:00
|
|
|
FreeLibrary((HMODULE)_handle);
|
2002-07-17 03:21:31 +08:00
|
|
|
#elif defined(__DARWIN_OSX__)
|
|
|
|
NSUnLinkModule(_handle, FALSE);
|
2002-07-23 18:48:22 +08:00
|
|
|
#elif defined(__hpux__)
|
|
|
|
// fortunately, shl_t is a pointer
|
|
|
|
shl_unload (static_cast<shl_t>(_handle));
|
2002-07-17 03:21:31 +08:00
|
|
|
#else // other unix
|
2001-09-20 05:08:56 +08:00
|
|
|
dlclose(_handle);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DynamicLibrary* DynamicLibrary::loadLibrary(const std::string& libraryName)
|
|
|
|
{
|
|
|
|
|
2003-03-10 19:57:17 +08:00
|
|
|
HANDLE handle = NULL;
|
|
|
|
|
|
|
|
std::string fullLibraryName = osgDB::findLibraryFile(libraryName);
|
|
|
|
if (!fullLibraryName.empty()) handle = getLibraryHandle( fullLibraryName ); // try the lib we have found
|
|
|
|
else handle = getLibraryHandle( libraryName ); // havn't found a lib ourselves, see if the OS can find it simply from the library name.
|
|
|
|
|
2002-12-16 21:40:58 +08:00
|
|
|
if (handle) return new DynamicLibrary(libraryName,handle);
|
2003-03-10 19:57:17 +08:00
|
|
|
|
|
|
|
// else no lib found so report errors.
|
2003-12-10 19:40:58 +08:00
|
|
|
notify(WARN) << "DynamicLibrary::failed loading \""<<libraryName<<"\""<<std::endl;
|
2003-03-10 19:57:17 +08:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-12-10 19:40:58 +08:00
|
|
|
DynamicLibrary::HANDLE DynamicLibrary::getLibraryHandle( const std::string& libraryName)
|
2003-03-10 19:57:17 +08:00
|
|
|
{
|
|
|
|
HANDLE handle = NULL;
|
|
|
|
|
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
handle = LoadLibrary( libraryName.c_str() );
|
2002-07-17 03:21:31 +08:00
|
|
|
#elif defined(__DARWIN_OSX__)
|
|
|
|
NSObjectFileImage image;
|
|
|
|
// NSModule os_handle = NULL;
|
2003-03-10 19:57:17 +08:00
|
|
|
if (NSCreateObjectFileImageFromFile(libraryName.c_str(), &image) == NSObjectFileImageSuccess) {
|
|
|
|
// os_handle = NSLinkModule(image, libraryName.c_str(), TRUE);
|
|
|
|
handle = NSLinkModule(image, libraryName.c_str(), TRUE);
|
2002-07-17 03:21:31 +08:00
|
|
|
NSDestroyObjectFileImage(image);
|
|
|
|
}
|
2002-07-23 18:48:22 +08:00
|
|
|
#elif defined(__hpux__)
|
|
|
|
// BIND_FIRST is neccessary for some reason
|
2003-12-10 19:40:58 +08:00
|
|
|
handle = shl_load ( libraryName.c_str(), BIND_DEFERRED|BIND_FIRST|BIND_VERBOSE, 0);
|
2003-03-10 19:57:17 +08:00
|
|
|
return handle;
|
2002-07-17 03:21:31 +08:00
|
|
|
#else // other unix
|
2003-11-06 12:08:53 +08:00
|
|
|
|
|
|
|
// dlopen will not work with files in the current directory unless
|
|
|
|
// they are prefaced with './' (DB - Nov 5, 2003).
|
|
|
|
std::string localLibraryName;
|
|
|
|
if( libraryName == osgDB::getSimpleFileName( libraryName ) )
|
|
|
|
localLibraryName = "./" + libraryName;
|
|
|
|
else
|
|
|
|
localLibraryName = libraryName;
|
|
|
|
handle = dlopen( localLibraryName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
|
2003-11-05 12:56:08 +08:00
|
|
|
if( handle == NULL )
|
2003-11-06 12:08:53 +08:00
|
|
|
notify(WARN) << "DynamicLibrary::getLibraryHandle( "<< libraryName << ") - dlopen(): " << dlerror() << std::endl;
|
2001-09-20 05:08:56 +08:00
|
|
|
#endif
|
2003-03-10 19:57:17 +08:00
|
|
|
return handle;
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
DynamicLibrary::PROC_ADDRESS DynamicLibrary::getProcAddress(const std::string& procName)
|
|
|
|
{
|
|
|
|
if (_handle==NULL) return NULL;
|
2002-01-04 05:34:57 +08:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
2002-07-17 03:21:31 +08:00
|
|
|
return (DynamicLibrary::PROC_ADDRESS)GetProcAddress( (HMODULE)_handle,
|
|
|
|
procName.c_str() );
|
|
|
|
#elif defined(__DARWIN_OSX__)
|
|
|
|
std::string temp("_");
|
|
|
|
NSSymbol symbol;
|
|
|
|
temp += procName; // Mac OS X prepends an underscore on function names
|
|
|
|
symbol = NSLookupAndBindSymbol(temp.c_str());
|
|
|
|
return NSAddressOfSymbol(symbol);
|
2002-07-23 18:48:22 +08:00
|
|
|
#elif defined(__hpux__)
|
|
|
|
void* result = NULL;
|
|
|
|
if (shl_findsym (reinterpret_cast<shl_t*>(&_handle), procName.c_str(), TYPE_PROCEDURE, result) == 0)
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
notify(WARN) << "DynamicLibrary::failed looking up " << procName << std::endl;
|
|
|
|
notify(WARN) << "DynamicLibrary::error " << strerror(errno) << std::endl;
|
|
|
|
return NULL;
|
|
|
|
}
|
2002-07-17 03:21:31 +08:00
|
|
|
#else // other unix
|
2002-08-04 02:11:21 +08:00
|
|
|
void* sym = dlsym( _handle, procName.c_str() );
|
|
|
|
if (!sym) {
|
|
|
|
notify(WARN) << "DynamicLibrary::failed looking up " << procName << std::endl;
|
|
|
|
notify(WARN) << "DynamicLibrary::error " << dlerror() << std::endl;
|
|
|
|
}
|
|
|
|
return sym;
|
2001-09-20 05:08:56 +08:00
|
|
|
#endif
|
|
|
|
return NULL;
|
|
|
|
}
|