-#include "wx/module.h"
-
-#if defined(__DARWIN__)
-/* Porting notes:
- * The dlopen port is a port from dl_next.xs by Anno Siegel.
- * dl_next.xs is itself a port from dl_dlopen.xs by Paul Marquess.
- * The method used here is just to supply the sun style dlopen etc.
- * functions in terms of Darwin NS*.
- */
-void *dlopen(const char *path, int mode /* mode is ignored */);
-void *dlsym(void *handle, const char *symbol);
-int dlclose(void *handle);
-const char *dlerror(void);
-#endif
-
-// ============================================================================
-// implementation
-// ============================================================================
-
-// ---------------------------------------------------------------------------
-// wxDynamicLibrary
-// ---------------------------------------------------------------------------
-
-//FIXME: This class isn't really common at all, it should be moved into
-// platform dependent files.
-
-#if defined(__WINDOWS__) || defined(__WXPM__) || defined(__EMX__)
- const wxChar *wxDynamicLibrary::ms_dllext = _T(".dll");
-#elif defined(__UNIX__)
- #if defined(__HPUX__)
- const wxChar *wxDynamicLibrary::ms_dllext = _T(".sl");
- #else
- const wxChar *wxDynamicLibrary::ms_dllext = _T(".so");
- #endif
-#endif
-
-wxDllType wxDynamicLibrary::GetProgramHandle()
-{
-#if defined( HAVE_DLOPEN ) && !defined(__EMX__)
- return dlopen(0, RTLD_LAZY);
-#elif defined (HAVE_SHL_LOAD)
- return PROG_HANDLE;
-#else
- wxFAIL_MSG( wxT("This method is not implemented under Windows or OS/2"));
- return 0;
-#endif
-}
-
-bool wxDynamicLibrary::Load(wxString libname, int flags)
-{
- wxASSERT_MSG(m_handle == 0, _T("Library already loaded."));
-
- // add the proper extension for the DLL ourselves unless told not to
- if ( !(flags & wxDL_VERBATIM) )
- {
- // and also check that the libname doesn't already have it
- wxString ext;
- wxFileName::SplitPath(libname, NULL, NULL, &ext);
- if ( ext.empty() )
- {
- libname += GetDllExt();
- }
- }
-
- // different ways to load a shared library
- //
- // FIXME: should go to the platform-specific files!
-#if defined(__WXMAC__) && !defined(__DARWIN__)
- FSSpec myFSSpec;
- Ptr myMainAddr;
- Str255 myErrName;
-
- wxMacFilename2FSSpec( libname , &myFSSpec );
-
- if( GetDiskFragment( &myFSSpec,
- 0,
- kCFragGoesToEOF,
- "\p",
- kPrivateCFragCopy,
- &m_handle,
- &myMainAddr,
- myErrName ) != noErr )
- {
- p2cstr( myErrName );
- wxLogSysError( _("Failed to load shared library '%s' Error '%s'"),
- libname.c_str(),
- (char*)myErrName );
- m_handle = 0;
- }
-
-#elif defined(__WXPM__) || defined(__EMX__)
- char err[256] = "";
- DosLoadModule(err, sizeof(err), libname.c_str(), &m_handle);
-
-#elif defined(HAVE_DLOPEN) || defined(__DARWIN__)
-
-#if defined(__VMS) || defined(__DARWIN__)
- m_handle = dlopen(libname.c_str(), 0); // The second parameter is ignored
-#else // !__VMS && !__DARWIN__
- int rtldFlags = 0;
-
- if ( flags & wxDL_LAZY )
- {
- wxASSERT_MSG( (flags & wxDL_NOW) == 0,
- _T("wxDL_LAZY and wxDL_NOW are mutually exclusive.") );
-#ifdef RTLD_LAZY
- rtldFlags |= RTLD_LAZY;
-#else
- wxLogDebug(_T("wxDL_LAZY is not supported on this platform"));
-#endif
- }
- else if ( flags & wxDL_NOW )
- {
-#ifdef RTLD_NOW
- rtldFlags |= RTLD_NOW;
-#else
- wxLogDebug(_T("wxDL_NOW is not supported on this platform"));
-#endif
- }
-
- if ( flags & wxDL_GLOBAL )
- {
-#ifdef RTLD_GLOBAL
- rtldFlags |= RTLD_GLOBAL;
-#else
- wxLogDebug(_T("RTLD_GLOBAL is not supported on this platform."));
-#endif
- }
-
- m_handle = dlopen(libname.fn_str(), rtldFlags);
-#endif // __VMS || __DARWIN__ ?
-
-#elif defined(HAVE_SHL_LOAD)
- int shlFlags = 0;
-
- if( flags & wxDL_LAZY )
- {
- wxASSERT_MSG( (flags & wxDL_NOW) == 0,
- _T("wxDL_LAZY and wxDL_NOW are mutually exclusive.") );
- shlFlags |= BIND_DEFERRED;
- }
- else if( flags & wxDL_NOW )
- {
- shlFlags |= BIND_IMMEDIATE;
- }
- m_handle = shl_load(libname.fn_str(), BIND_DEFERRED, 0);
-
-#elif defined(__WINDOWS__)
- m_handle = ::LoadLibrary(libname.c_str());
-#else
- #error "runtime shared lib support not implemented on this platform"
-#endif
-
- if ( m_handle == 0 )
- {
- wxString msg(_("Failed to load shared library '%s'"));
-#if defined(HAVE_DLERROR) && !defined(__EMX__)
-
-#if wxUSE_UNICODE
- wxWCharBuffer buffer = wxConvLocal.cMB2WC( dlerror() );
- const wxChar *err = buffer;
-#else
- const wxChar *err = dlerror();
-#endif
-
- if( err )
- wxLogError( msg, err );
-#else
- wxLogSysError( msg, libname.c_str() );
-#endif
- }
-
- return IsLoaded();
-}
-
-void wxDynamicLibrary::Unload()
-{
- if( IsLoaded() )
- {
-#if defined(__WXPM__) || defined(__EMX__)
- DosFreeModule( m_handle );
-#elif defined(HAVE_DLOPEN) || defined(__DARWIN__)
- dlclose( m_handle );
-#elif defined(HAVE_SHL_LOAD)
- shl_unload( m_handle );
-#elif defined(__WINDOWS__)
- ::FreeLibrary( m_handle );
-#elif defined(__WXMAC__) && !defined(__DARWIN__)
- CloseConnection( (CFragConnectionID*) &m_handle );
-#else
-#error "runtime shared lib support not implemented"
-#endif
- m_handle = 0;
- }
-}
-
-void *wxDynamicLibrary::GetSymbol(const wxString &name, bool *success) const
-{
- wxCHECK_MSG( IsLoaded(), NULL,
- _T("Can't load symbol from unloaded library") );
-
- bool failed = FALSE;
- void *symbol = 0;
-
-#if defined(__WXMAC__) && !defined(__DARWIN__)
- Ptr symAddress;
- CFragSymbolClass symClass;
- Str255 symName;
-#if TARGET_CARBON
- c2pstrcpy( (StringPtr) symName, name );
-#else
- strcpy( (char *)symName, name );
- c2pstr( (char *)symName );
-#endif
- if( FindSymbol( dllHandle, symName, &symAddress, &symClass ) == noErr )
- symbol = (void *)symAddress;
-
-#elif defined(__WXPM__) || defined(__EMX__)
- DosQueryProcAddr( m_handle, 1L, name.c_str(), (PFN*)symbol );
-
-#elif defined(HAVE_DLOPEN) || defined(__DARWIN__)
- symbol = dlsym( m_handle, name.fn_str() );
-
-#elif defined(HAVE_SHL_LOAD)
- // use local variable since shl_findsym modifies the handle argument
- // to indicate where the symbol was found (GD)
- wxDllType the_handle = m_handle;
- if( shl_findsym( &the_handle, name.fn_str(), TYPE_UNDEFINED, &symbol ) != 0 )
- symbol = 0;
-
-#elif defined(__WINDOWS__)
- symbol = (void*) ::GetProcAddress( m_handle, name.mb_str() );
-
-#else
-#error "runtime shared lib support not implemented"
-#endif
-
- if ( !symbol )
- {
-#if defined(HAVE_DLERROR) && !defined(__EMX__)
-
-#if wxUSE_UNICODE
- wxWCharBuffer buffer = wxConvLocal.cMB2WC( dlerror() );
- const wxChar *err = buffer;
-#else
- const wxChar *err = dlerror();
-#endif
-
- if( err )
- {
- wxLogError(wxT("%s"), err);
- }
-#else
- failed = TRUE;
- wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
- name.c_str());
-#endif
- }
- if( success )
- *success = !failed;
-
- return symbol;
-}