removed duplicated code from dynlib.h and dynload.h

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22452 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2003-08-01 21:12:40 +00:00
parent 87baeeaff6
commit 1948bb3274
7 changed files with 721 additions and 1058 deletions

3
configure vendored
View File

@@ -32157,7 +32157,8 @@ if test "$wxUSE_DYNAMIC_LOADER" = "yes" ; then
#define wxUSE_DYNAMIC_LOADER 1 #define wxUSE_DYNAMIC_LOADER 1
_ACEOF _ACEOF
elif test "$wxUSE_DYNLIB_CLASS" = "yes" ; then fi
if test "$wxUSE_DYNLIB_CLASS" = "yes" ; then
cat >>confdefs.h <<\_ACEOF cat >>confdefs.h <<\_ACEOF
#define wxUSE_DYNLIB_CLASS 1 #define wxUSE_DYNLIB_CLASS 1
_ACEOF _ACEOF

View File

@@ -4714,7 +4714,8 @@ fi
if test "$wxUSE_DYNAMIC_LOADER" = "yes" ; then if test "$wxUSE_DYNAMIC_LOADER" = "yes" ; then
AC_DEFINE(wxUSE_DYNAMIC_LOADER) AC_DEFINE(wxUSE_DYNAMIC_LOADER)
elif test "$wxUSE_DYNLIB_CLASS" = "yes" ; then fi
if test "$wxUSE_DYNLIB_CLASS" = "yes" ; then
AC_DEFINE(wxUSE_DYNLIB_CLASS) AC_DEFINE(wxUSE_DYNLIB_CLASS)
fi fi

View File

@@ -851,6 +851,16 @@
# endif # endif
#endif /* wxUSE_UNICODE_MSLU */ #endif /* wxUSE_UNICODE_MSLU */
#if !wxUSE_DYNLIB_CLASS
# if wxUSE_DYNAMIC_LOADER
# ifdef wxABORT_ON_CONFIG_ERROR
# error "wxUSE_DYNAMIC_LOADER requires wxUSE_DYNLIB_CLASS."
# else
# define wxUSE_DYNLIB_CLASS 1
# endif
# endif
#endif /* wxUSE_DYNLIB_CLASS */
/* the rest of the tests is for the GUI settings only */ /* the rest of the tests is for the GUI settings only */
#if wxUSE_GUI #if wxUSE_GUI

View File

@@ -18,58 +18,184 @@
#include "wx/setup.h" #include "wx/setup.h"
#if wxUSE_DYNAMIC_LOADER #if wxUSE_DYNLIB_CLASS
#include "wx/dynload.h" // Use the new (version of) wxDynamicLibrary instead
#elif wxUSE_DYNLIB_CLASS
#include "wx/string.h" #include "wx/string.h"
#include "wx/list.h"
#include "wx/hash.h"
// this is normally done by configure, but I leave it here for now... // FIXME: can this go in private.h or something too??
#if defined(__UNIX__) && !(defined(HAVE_DLOPEN) || defined(HAVE_SHL_LOAD))
# if defined(__LINUX__) || defined(__SOLARIS__) || defined(__SUNOS__) || defined(__FREEBSD__)
# define HAVE_DLOPEN
# elif defined(__HPUX__)
# define HAVE_SHL_LOAD
# endif // Unix flavour
#endif // !Unix or already have some HAVE_xxx defined
// Note: WXPM/EMX has to be tested first, since we want to use
// native version, even if configure detected presence of DLOPEN.
#if defined(__WXPM__) || defined(__EMX__) #if defined(__WXPM__) || defined(__EMX__)
# define INCL_DOS #define INCL_DOS
# include <os2.h> #include <os2.h>
typedef HMODULE wxDllType;
#elif defined(HAVE_DLOPEN)
# include <dlfcn.h>
typedef void *wxDllType;
#elif defined(HAVE_SHL_LOAD)
# include <dl.h>
typedef shl_t wxDllType;
#elif defined(__WINDOWS__)
# include <windows.h> // needed to get HMODULE
typedef HMODULE wxDllType;
#elif defined(__DARWIN__)
typedef void *wxDllType;
#elif defined(__WXMAC__)
typedef void *wxDllType;
#else
# error "wxLibrary can't be compiled on this platform, sorry."
#endif // OS
// LoadLibrary is defined in windows.h as LoadLibraryA, but wxDllLoader method
// should be called LoadLibrary, not LoadLibraryA or LoadLibraryW!
#if defined(__WIN32__) && defined(LoadLibrary)
# include "wx/msw/winundef.h"
#endif #endif
#ifdef __WXMSW__
#include "wx/msw/private.h"
#endif
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
// Note: WXPM/EMX has to be tested first, since we want to use
// native version, even if configure detected presence of DLOPEN.
#if defined(__WXPM__) || defined(__EMX__) || defined(__WINDOWS__)
typedef HMODULE wxDllType;
#elif defined(HAVE_DLOPEN)
#include <dlfcn.h>
typedef void *wxDllType;
#elif defined(HAVE_SHL_LOAD)
#include <dl.h>
typedef shl_t wxDllType;
#elif defined(__DARWIN__)
typedef void *wxDllType;
#elif defined(__WXMAC__)
typedef CFragConnectionID wxDllType;
#else
#error "Dynamic Loading classes can't be compiled on this platform, sorry."
#endif
// ---------------------------------------------------------------------------
// wxDynamicLibrary
// ---------------------------------------------------------------------------
//FIXME: This class isn't really common at all, it should be moved
// into platform dependent files.
// NOTE: this class is (deliberately) not virtual, do not attempt
// to use it polymorphically.
enum wxDLFlags
{
wxDL_LAZY = 0x00000001, // resolve undefined symbols at first use
wxDL_NOW = 0x00000002, // resolve undefined symbols on load
wxDL_GLOBAL = 0x00000004, // export extern symbols to subsequently
// loaded libs.
wxDL_VERBATIM = 0x00000008, // Attempt to load the supplied library
// name without appending the usual dll
// filename extension.
wxDL_NOSHARE = 0x00000010, // load new DLL, don't reuse already loaded
// FIXME: why? (VZ)
#ifdef __osf__
wxDL_DEFAULT = wxDL_LAZY
#else
wxDL_DEFAULT = wxDL_LAZY | wxDL_GLOBAL
#endif
};
enum wxDynamicLibraryCategory
{
wxDL_LIBRARY, // standard library
wxDL_MODULE, // loadable module/plugin
};
enum wxPluginCategory
{
wxDL_PLUGIN_GUI, // plugin that uses GUI classes
wxDL_PLUGIN_BASE, // wxBase-only plugin
};
class WXDLLIMPEXP_BASE wxDynamicLibrary
{
public:
// return a valid handle for the main program itself or NULL if
// back linking is not supported by the current platform (e.g. Win32)
static wxDllType GetProgramHandle();
// return the platform standard DLL extension (with leading dot)
static const wxChar *GetDllExt() { return ms_dllext; }
wxDynamicLibrary() : m_handle(0) {}
wxDynamicLibrary(const wxString& libname, int flags = wxDL_DEFAULT)
: m_handle(0)
{
Load(libname, flags);
}
~wxDynamicLibrary() { Unload(); }
// return TRUE if the library was loaded successfully
bool IsLoaded() const { return m_handle != 0; }
// load the library with the given name
// (full or not), return TRUE on success
bool Load(wxString libname, int flags = wxDL_DEFAULT);
// detach the library object from its handle, i.e. prevent the object
// from unloading the library in its dtor -- the caller is now
// responsible for doing this
wxDllType Detach() { wxDllType h = m_handle; m_handle = 0; return h; }
// unload the library, also done automatically in dtor
void Unload();
// Return the raw handle from dlopen and friends.
wxDllType GetLibHandle() const { return m_handle; }
// resolve a symbol in a loaded DLL, such as a variable or function
// name. 'name' is the (possibly mangled) name of the symbol.
// (use extern "C" to export unmangled names)
//
// Since it is perfectly valid for the returned symbol to actually be
// NULL, that is not always indication of an error. Pass and test the
// parameter 'success' for a true indication of success or failure to
// load the symbol.
//
// Returns a pointer to the symbol on success, or NULL if an error
// occurred or the symbol wasn't found.
void *GetSymbol(const wxString& name, bool *success = 0) const;
#if WXWIN_COMPATIBILITY_2_2
operator bool() const { return IsLoaded(); }
#endif
// return platform-specific name of dynamic library with proper extension
// and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
static wxString CanonicalizeName(const wxString& name,
wxDynamicLibraryCategory cat = wxDL_LIBRARY);
// return name of wxWindows plugin (adds compiler and version info
// to the filename):
static wxString CanonicalizePluginName(const wxString& name,
wxPluginCategory cat);
// return plugin directory on platforms where it makes sense and empty
// string on others:
static wxString GetPluginsDirectory();
protected:
// Platform specific shared lib suffix.
static const wxChar *ms_dllext;
// the handle to DLL or NULL
wxDllType m_handle;
// no copy ctor/assignment operators
// or we'd try to unload the library twice
DECLARE_NO_COPY_CLASS(wxDynamicLibrary)
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxDllLoader: low level DLL functions, use wxDynamicLibrary in your code // wxDllLoader: low level DLL functions, use wxDynamicLibrary in your code
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
/* /*
wxDllLoader is a class providing an interface similar to unix's dlopen(). wxDllLoader is a class providing an interface similar to unix's dlopen().
It is used by wxDynamicLibrary wxLibrary and manages the actual loading of It is used by wxDynamicLibrary wxLibrary and manages the actual loading of
@@ -89,7 +215,7 @@ public:
if success pointer is not NULL, it will be filled with TRUE if everything if success pointer is not NULL, it will be filled with TRUE if everything
went ok and FALSE otherwise went ok and FALSE otherwise
*/ */
static wxDllType LoadLibrary(const wxString& libname, bool *success = 0); static wxDllType LoadLibrary(const wxString& name, bool *success = NULL);
/* /*
This function unloads the shared library previously loaded with This function unloads the shared library previously loaded with
@@ -102,7 +228,7 @@ public:
itself or NULL if back linking is not supported by the current platform itself or NULL if back linking is not supported by the current platform
(e.g. Win32). (e.g. Win32).
*/ */
static wxDllType GetProgramHandle(); static wxDllType GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
/* /*
This function resolves a symbol in a loaded DLL, such as a This function resolves a symbol in a loaded DLL, such as a
@@ -113,78 +239,23 @@ public:
Returns the pointer to the symbol or NULL on error. Returns the pointer to the symbol or NULL on error.
*/ */
static void *GetSymbol(wxDllType dllHandle, static void *GetSymbol(wxDllType dllHandle, const wxString &name, bool *success = 0);
const wxString &name,
bool *success = NULL);
// return the standard DLL extension (with leading dot) for this platform // return the standard DLL extension (with leading dot) for this platform
static const wxString &GetDllExt() { return ms_dllext; } static wxString GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
private: private:
// forbid construction of objects
wxDllLoader(); wxDllLoader(); // forbid construction of objects
static const wxString ms_dllext;
}; };
// ----------------------------------------------------------------------------
// wxDynamicLibrary - friendly interface to wxDllLoader
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxDynamicLibrary
{
public:
// ctors
wxDynamicLibrary() { m_library = 0; }
wxDynamicLibrary(const wxString& name) { Load(name); }
// return TRUE if the library was loaded successfully
bool IsLoaded() const { return m_library != 0; }
operator bool() const { return IsLoaded(); }
// load the library with the given name (full or not), return TRUE on
// success
bool Load(const wxString& name)
{
m_library = wxDllLoader::LoadLibrary(name);
return IsLoaded();
}
// unload the library, also done automatically in dtor
void Unload()
{
if ( IsLoaded() )
wxDllLoader::UnloadLibrary(m_library);
}
// load a symbol from the library, return NULL if an error occured or
// symbol wasn't found
void *GetSymbol(const wxString& name) const
{
wxCHECK_MSG( IsLoaded(), NULL,
_T("can't load symbol from unloaded library") );
return wxDllLoader::GetSymbol(m_library, name);
}
// unload the library
//
// NB: dtor is not virtual, don't derive from this class
~wxDynamicLibrary() { Unload(); }
private:
// the handle to DLL or NULL
wxDllType m_library;
// no copy ctor/assignment operators (or we'd try to unload the library
// twice)
DECLARE_NO_COPY_CLASS(wxDynamicLibrary)
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxLibrary // wxLibrary
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "wx/hash.h"
class WXDLLIMPEXP_BASE wxLibrary : public wxObject class WXDLLIMPEXP_BASE wxLibrary : public wxObject
{ {
public: public:
@@ -231,6 +302,8 @@ protected:
extern WXDLLIMPEXP_DATA_BASE(wxLibraries) wxTheLibraries; extern WXDLLIMPEXP_DATA_BASE(wxLibraries) wxTheLibraries;
#endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Interesting defines // Interesting defines
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -25,183 +25,17 @@
#if wxUSE_DYNAMIC_LOADER #if wxUSE_DYNAMIC_LOADER
#include "wx/dynlib.h"
#include "wx/hashmap.h" #include "wx/hashmap.h"
#include "wx/module.h" #include "wx/module.h"
// FIXME: can this go in private.h or something too??
#if defined(__WXPM__) || defined(__EMX__)
#define INCL_DOS
#include <os2.h>
#endif
#ifdef __WXMSW__
#include "wx/msw/private.h"
#endif
class WXDLLIMPEXP_BASE wxPluginLibrary; class WXDLLIMPEXP_BASE wxPluginLibrary;
WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxPluginLibrary *, wxDLManifest);
WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxPluginLibrary *, wxDLManifest,
class WXDLLIMPEXP_BASE);
typedef wxDLManifest wxDLImports; typedef wxDLManifest wxDLImports;
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
// Note: WXPM/EMX has to be tested first, since we want to use
// native version, even if configure detected presence of DLOPEN.
#if defined(__WXPM__) || defined(__EMX__) || defined(__WINDOWS__)
typedef HMODULE wxDllType;
#elif defined(HAVE_DLOPEN)
#include <dlfcn.h>
typedef void *wxDllType;
#elif defined(HAVE_SHL_LOAD)
#include <dl.h>
typedef shl_t wxDllType;
#elif defined(__DARWIN__)
typedef void *wxDllType;
#elif defined(__WXMAC__)
typedef CFragConnectionID wxDllType;
#else
#error "Dynamic Loading classes can't be compiled on this platform, sorry."
#endif
// ---------------------------------------------------------------------------
// wxDynamicLibrary
// ---------------------------------------------------------------------------
//FIXME: This class isn't really common at all, it should be moved
// into platform dependent files.
// NOTE: this class is (deliberately) not virtual, do not attempt
// to use it polymorphically.
enum wxDLFlags
{
wxDL_LAZY = 0x00000001, // resolve undefined symbols at first use
wxDL_NOW = 0x00000002, // resolve undefined symbols on load
wxDL_GLOBAL = 0x00000004, // export extern symbols to subsequently
// loaded libs.
wxDL_VERBATIM = 0x00000008, // Attempt to load the supplied library
// name without appending the usual dll
// filename extension.
wxDL_NOSHARE = 0x00000010, // load new DLL, don't reuse already loaded
// FIXME: why? (VZ)
#ifdef __osf__
wxDL_DEFAULT = wxDL_LAZY
#else
wxDL_DEFAULT = wxDL_LAZY | wxDL_GLOBAL
#endif
};
enum wxDynamicLibraryCategory
{
wxDL_LIBRARY, // standard library
wxDL_MODULE, // loadable module/plugin
};
enum wxPluginCategory
{
wxDL_PLUGIN_GUI, // plugin that uses GUI classes
wxDL_PLUGIN_BASE, // wxBase-only plugin
};
class WXDLLIMPEXP_BASE wxDynamicLibrary
{
public:
// return a valid handle for the main program itself or NULL if
// back linking is not supported by the current platform (e.g. Win32)
static wxDllType GetProgramHandle();
// return the platform standard DLL extension (with leading dot)
static const wxChar *GetDllExt() { return ms_dllext; }
wxDynamicLibrary() : m_handle(0) {}
wxDynamicLibrary(wxString libname, int flags = wxDL_DEFAULT)
: m_handle(0)
{
Load(libname, flags);
}
~wxDynamicLibrary() { Unload(); }
// return TRUE if the library was loaded successfully
bool IsLoaded() const { return m_handle != 0; }
// load the library with the given name
// (full or not), return TRUE on success
bool Load(wxString libname, int flags = wxDL_DEFAULT);
// detach the library object from its handle, i.e. prevent the object
// from unloading the library in its dtor -- the caller is now
// responsible for doing this
wxDllType Detach() { wxDllType h = m_handle; m_handle = 0; return h; }
// unload the library, also done automatically in dtor
void Unload();
// Return the raw handle from dlopen and friends.
wxDllType GetLibHandle() const { return m_handle; }
// resolve a symbol in a loaded DLL, such as a variable or function
// name. 'name' is the (possibly mangled) name of the symbol.
// (use extern "C" to export unmangled names)
//
// Since it is perfectly valid for the returned symbol to actually be
// NULL, that is not always indication of an error. Pass and test the
// parameter 'success' for a true indication of success or failure to
// load the symbol.
//
// Returns a pointer to the symbol on success, or NULL if an error
// occurred or the symbol wasn't found.
void *GetSymbol(const wxString& name, bool *success = 0) const;
#if WXWIN_COMPATIBILITY_2_2
operator bool() const { return IsLoaded(); }
#endif
// return platform-specific name of dynamic library with proper extension
// and prefix (e.g. "foo.dll" on Windows or "libfoo.so" on Linux)
static wxString CanonicalizeName(const wxString& name,
wxDynamicLibraryCategory cat = wxDL_LIBRARY);
// return name of wxWindows plugin (adds compiler and version info
// to the filename):
static wxString CanonicalizePluginName(const wxString& name,
wxPluginCategory cat);
// return plugin directory on platforms where it makes sense and empty
// string on others:
static wxString GetPluginsDirectory();
protected:
// Platform specific shared lib suffix.
static const wxChar *ms_dllext;
// the handle to DLL or NULL
wxDllType m_handle;
// no copy ctor/assignment operators
// or we'd try to unload the library twice
DECLARE_NO_COPY_CLASS(wxDynamicLibrary)
};
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// wxPluginLibrary // wxPluginLibrary
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -325,34 +159,6 @@ private:
}; };
// ---------------------------------------------------------------------------
// wxDllLoader
// ---------------------------------------------------------------------------
// Cross platform wrapper for dlopen and friends.
// There are no instances of this class, it simply
// serves as a namespace for its static member functions.
#if WXWIN_COMPATIBILITY_2_2
class WXDLLIMPEXP_BASE wxDllLoader
{
public:
static wxDllType LoadLibrary(const wxString& name, bool *success = NULL);
static void UnloadLibrary(wxDllType dll);
static wxDllType GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
static void *GetSymbol(wxDllType dllHandle, const wxString &name, bool *success = 0);
static wxString GetDllExt() { return wxDynamicLibrary::GetDllExt(); }
private:
wxDllLoader(); // forbid construction of objects
};
#endif
#endif // wxUSE_DYNAMIC_LOADER #endif // wxUSE_DYNAMIC_LOADER
#endif // _WX_DYNAMICLOADER_H__ #endif // _WX_DYNAMICLOADER_H__

View File

@@ -27,7 +27,7 @@
#pragma hdrstop #pragma hdrstop
#endif #endif
#if wxUSE_DYNLIB_CLASS && !wxUSE_DYNAMIC_LOADER #if wxUSE_DYNLIB_CLASS
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
#include "wx/msw/private.h" #include "wx/msw/private.h"
@@ -37,396 +37,30 @@
#include "wx/filefn.h" #include "wx/filefn.h"
#include "wx/intl.h" #include "wx/intl.h"
#include "wx/log.h" #include "wx/log.h"
#include "wx/utils.h"
#include "wx/filename.h" // for SplitPath()
#if defined(__WXMAC__) #if defined(__WXMAC__)
#include "wx/mac/private.h" #include "wx/mac/private.h"
#endif #endif
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
#if defined(__WXPM__) || defined(__EMX__) // ============================================================================
# define INCL_DOS // implementation
# include <os2.h> // ============================================================================
# define wxDllOpen(error, lib, handle) DosLoadModule(error, sizeof(error), lib, &handle)
# define wxDllGetSymbol(handle, modaddr) DosQueryProcAddr(handle, 1L, NULL, (PFN*)modaddr)
# define wxDllClose(handle) DosFreeModule(handle)
#elif defined(HAVE_DLOPEN)
// note about dlopen() flags: we use RTLD_NOW to have more Windows-like
// behaviour (Win won't let you load a library with missing symbols) and
// RTLD_GLOBAL because it is needed sometimes and probably doesn't hurt
// otherwise. On True64-Unix RTLD_GLOBAL is not allowed and on VMS the
// second argument on dlopen is ignored.
#ifdef __VMS
# define wxDllOpen(lib) dlopen(lib.fn_str(), 0 )
#elif defined( __osf__ )
# define wxDllOpen(lib) dlopen(lib.fn_str(), RTLD_LAZY )
#else
# define wxDllOpen(lib) dlopen(lib.fn_str(), RTLD_LAZY | RTLD_GLOBAL)
#endif
#define wxDllGetSymbol(handle, name) dlsym(handle, name)
# define wxDllClose dlclose
#elif defined(HAVE_SHL_LOAD)
# define wxDllOpen(lib) shl_load(lib.fn_str(), BIND_DEFERRED, 0)
# define wxDllClose shl_unload
static inline void *wxDllGetSymbol(shl_t handle, const wxString& name) #if defined(__DARWIN__)
{ // ---------------------------------------------------------------------------
void *sym; // For Darwin/Mac OS X
if ( shl_findsym(&handle, name.mb_str(), TYPE_UNDEFINED, &sym) == 0 ) // supply the sun style dlopen functions in terms of Darwin NS*
return sym; // ---------------------------------------------------------------------------
else
return 0;
}
#elif defined(__DARWIN__)
/* Porting notes: /* Porting notes:
* The dlopen port is a port from dl_next.xs by Anno Siegel. * 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. * 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. * The method used here is just to supply the sun style dlopen etc.
* functions in terms of Darwin NS*. * 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);
# define wxDllOpen(lib) dlopen(lib.fn_str(), 0)
# define wxDllGetSymbol(handle, name) dlsym(handle, name)
# define wxDllClose dlclose
#elif defined(__WINDOWS__)
// using LoadLibraryEx under Win32 to avoid name clash with LoadLibrary
# ifdef __WIN32__
#ifdef _UNICODE
#ifdef __WXWINCE__
# define wxDllOpen(lib) ::LoadLibrary(lib)
#else
# define wxDllOpen(lib) ::LoadLibraryExW(lib, 0, 0)
#endif
#else
# define wxDllOpen(lib) ::LoadLibraryExA(lib, 0, 0)
#endif
# else // Win16
# define wxDllOpen(lib) ::LoadLibrary(lib)
# endif // Win32/16
# define wxDllGetSymbol(handle, name) ::GetProcAddress(handle, name)
# define wxDllClose ::FreeLibrary
#elif defined(__WXMAC__)
# define wxDllClose(handle) CloseConnection(&((CFragConnectionID)handle))
#else
# error "Don't know how to load shared libraries on this platform."
#endif // OS
// ---------------------------------------------------------------------------
// Global variables
// ---------------------------------------------------------------------------
wxLibraries wxTheLibraries;
// ============================================================================
// implementation
// ============================================================================
// construct the full name from the base shared object name: adds a .dll
// suffix under Windows or .so under Unix
static wxString ConstructLibraryName(const wxString& basename)
{
wxString fullname;
fullname << basename << wxDllLoader::GetDllExt();
return fullname;
}
// ---------------------------------------------------------------------------
// wxLibrary (one instance per dynamic library)
// ---------------------------------------------------------------------------
wxLibrary::wxLibrary(wxDllType handle)
{
typedef wxClassInfo *(*t_get_first)(void);
t_get_first get_first;
m_handle = handle;
// Some system may use a local heap for library.
get_first = (t_get_first)GetSymbol(_T("wxGetClassFirst"));
// It is a wxWindows DLL.
if (get_first)
PrepareClasses(get_first());
}
wxLibrary::~wxLibrary()
{
if ( m_handle )
{
wxDllClose(m_handle);
}
}
wxObject *wxLibrary::CreateObject(const wxString& name)
{
wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
if (!info)
return NULL;
return info->CreateObject();
}
void wxLibrary::PrepareClasses(wxClassInfo *first)
{
// Index all class infos by their class name
wxClassInfo *info = first;
while (info)
{
if (info->m_className)
classTable.Put(info->m_className, (wxObject *)info);
info = info->m_next;
}
// Set base pointers for each wxClassInfo
info = first;
while (info)
{
if (info->GetBaseClassName1())
info->m_baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
if (info->GetBaseClassName2())
info->m_baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
info = info->m_next;
}
}
void *wxLibrary::GetSymbol(const wxString& symbname)
{
return wxDllLoader::GetSymbol(m_handle, symbname);
}
// ---------------------------------------------------------------------------
// wxDllLoader
// ---------------------------------------------------------------------------
#if defined(__WINDOWS__) || defined(__WXPM__) || defined(__EMX__)
const wxString wxDllLoader::ms_dllext( _T(".dll") );
#elif defined(__UNIX__)
#if defined(__HPUX__)
const wxString wxDllLoader::ms_dllext( _T(".sl") );
#else
const wxString wxDllLoader::ms_dllext( _T(".so") );
#endif
#elif defined(__WXMAC__)
const wxString wxDllLoader::ms_dllext( _T("") );
#endif
/* static */
wxDllType wxDllLoader::GetProgramHandle()
{
#if defined( HAVE_DLOPEN ) && !defined(__EMX__)
// optain handle for main program
return dlopen(NULL, RTLD_NOW/*RTLD_LAZY*/);
#elif defined (HAVE_SHL_LOAD)
// shl_findsymbol with NULL handle looks up in main program
return 0;
#else
wxFAIL_MSG( wxT("This method is not implemented under Windows or OS/2"));
return 0;
#endif
}
/* static */
wxDllType wxDllLoader::LoadLibrary(const wxString & libname, bool *success)
{
wxDllType handle;
bool failed = FALSE;
#if defined(__WXMAC__) && !defined(__UNIX__)
FSSpec myFSSpec;
Ptr myMainAddr;
Str255 myErrName;
wxMacFilename2FSSpec( libname , &myFSSpec );
if( GetDiskFragment( &myFSSpec,
0,
kCFragGoesToEOF,
"\p",
kPrivateCFragCopy,
&((CFragConnectionID)handle),
&myMainAddr,
myErrName ) != noErr )
{
p2cstr( myErrName );
wxLogSysError( _("Failed to load shared library '%s' Error '%s'"),
libname.c_str(),
(char*)myErrName );
handle = 0;
failed = TRUE;
}
#elif defined(__WXPM__) || defined(__EMX__)
char zError[256] = "";
wxDllOpen(zError, libname, handle);
#else
handle = wxDllOpen(libname);
#endif
if ( !handle )
{
wxString msg(_("Failed to load shared library '%s'"));
#ifdef HAVE_DLERROR
const wxChar *err = dlerror();
if( err )
{
failed = TRUE;
wxLogError( msg, err );
}
#else
failed = TRUE;
wxLogSysError( msg, libname.c_str() );
#endif
}
if ( success )
*success = !failed;
return handle;
}
/* static */
void wxDllLoader::UnloadLibrary(wxDllType handle)
{
wxDllClose(handle);
}
/* static */
void *wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name, bool *success)
{
bool failed = FALSE;
void *symbol = 0;
#if defined(__WXMAC__) && !defined(__UNIX__)
Ptr symAddress;
CFragSymbolClass symClass;
Str255 symName;
wxMacStringToPascal( name.c_str() , symName ) ;
if( FindSymbol( ((CFragConnectionID)dllHandle), symName, &symAddress, &symClass ) == noErr )
symbol = (void *)symAddress;
#elif defined(__WXPM__) || defined(__EMX__)
wxDllGetSymbol(dllHandle, symbol);
#else // Windows or Unix
// mb_str() is necessary in Unicode build
//
// "void *" cast is needed by gcc 3.1 + w32api 1.4, don't ask me why
#ifdef __WXWINCE__
symbol = (void *) wxDllGetSymbol(dllHandle, name.c_str());
#else
symbol = (void *) wxDllGetSymbol(dllHandle, name.mb_str());
#endif
#endif // OS
if ( !symbol )
{
#ifdef HAVE_DLERROR
const wxChar *err = dlerror();
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;
}
// ---------------------------------------------------------------------------
// wxLibraries (only one instance should normally exist)
// ---------------------------------------------------------------------------
wxLibraries::wxLibraries():m_loaded(wxKEY_STRING)
{
}
wxLibraries::~wxLibraries()
{
wxNode *node = m_loaded.First();
while (node) {
wxLibrary *lib = (wxLibrary *)node->Data();
delete lib;
node = node->Next();
}
}
wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
{
wxLibrary *lib;
wxClassInfo *old_sm_first;
wxNode *node = m_loaded.Find(name.GetData());
if (node != NULL)
return ((wxLibrary *)node->Data());
// If DLL shares data, this is necessary.
old_sm_first = wxClassInfo::sm_first;
wxClassInfo::sm_first = NULL;
wxString libname = ConstructLibraryName(name);
bool success = FALSE;
wxDllType handle = wxDllLoader::LoadLibrary(libname, &success);
if(success)
{
lib = new wxLibrary(handle);
wxClassInfo::sm_first = old_sm_first;
m_loaded.Append(name.GetData(), lib);
}
else
lib = NULL;
return lib;
}
wxObject *wxLibraries::CreateObject(const wxString& path)
{
wxNode *node = m_loaded.First();
wxObject *obj;
while (node) {
obj = ((wxLibrary *)node->Data())->CreateObject(path);
if (obj)
return obj;
node = node->Next();
}
return NULL;
}
#endif // wxUSE_DYNLIB_CLASS && !wxUSE_DYNAMIC_LOADER
#if defined(__DARWIN__) && (wxUSE_DYNLIB_CLASS || wxUSE_DYNAMIC_LOADER)
// ---------------------------------------------------------------------------
// For Darwin/Mac OS X
// supply the sun style dlopen functions in terms of Darwin NS*
// ---------------------------------------------------------------------------
#include <stdio.h> #include <stdio.h>
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
@@ -505,4 +139,346 @@ void *dlsym(void *handle, const char *symbol)
return addr; return addr;
} }
#endif // defined(__DARWIN__) && (wxUSE_DYNLIB_CLASS || wxUSE_DYNAMIC_LOADER) #endif // defined(__DARWIN__)
// ---------------------------------------------------------------------------
// 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;
}
/*static*/
wxString wxDynamicLibrary::CanonicalizeName(const wxString& name,
wxDynamicLibraryCategory cat)
{
#ifdef __UNIX__
if ( cat == wxDL_MODULE )
return name + GetDllExt();
else
return wxString(_T("lib")) + name + GetDllExt();
#else
return name + GetDllExt();
#endif
}
/*static*/
wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
wxPluginCategory cat)
{
wxString suffix;
if ( cat == wxDL_PLUGIN_GUI )
{
suffix = wxString::FromAscii(
#if defined(__WXMSW__)
"msw"
#elif defined(__WXGTK__)
"gtk"
#elif defined(__WXMGL__)
"mgl"
#elif defined(__WXMOTIF__)
"motif"
#elif defined(__WXOS2__)
"pm"
#elif defined(__WXX11__)
"x11"
#elif defined(__WXMAC__)
"mac"
#elif defined(__WXCOCOA__)
"cocoa"
#endif
);
#ifdef __WXUNIVERSAL__
suffix << _T("univ");
#endif
}
#if wxUSE_UNICODE
suffix << _T('u');
#endif
#ifdef __WXDEBUG__
suffix << _T('d');
#endif
if ( !suffix.empty() )
suffix = wxString(_T("_")) + suffix;
#ifdef __UNIX__
#if (wxMINOR_VERSION % 2) == 0
#define wxDLLVER(x,y,z) "-" #x "." #y
#else
#define wxDLLVER(x,y,z) "-" #x "." #y "." #z
#endif
#else
#if (wxMINOR_VERSION % 2) == 0
#define wxDLLVER(x,y,z) #x #y
#else
#define wxDLLVER(x,y,z) #x #y #z
#endif
#endif
suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION,
wxRELEASE_NUMBER));
#undef wxDLLVER
return CanonicalizeName(name + suffix, wxDL_MODULE);
}
/*static*/
wxString wxDynamicLibrary::GetPluginsDirectory()
{
#ifdef __UNIX__
wxString format = wxGetInstallPrefix();
format << wxFILE_SEP_PATH
<< wxT("lib") << wxFILE_SEP_PATH
<< wxT("wx") << wxFILE_SEP_PATH
<< wxT("%i.%i");
wxString dir;
dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
return dir;
#else
return wxEmptyString;
#endif
}
#endif // wxUSE_DYNLIB_CLASS

View File

@@ -37,367 +37,11 @@
#include "wx/utils.h" #include "wx/utils.h"
#endif #endif
#include "wx/filename.h" // for SplitPath()
#include "wx/strconv.h" #include "wx/strconv.h"
#include "wx/dynload.h" #include "wx/dynload.h"
#include "wx/module.h" #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;
}
/*static*/
wxString wxDynamicLibrary::CanonicalizeName(const wxString& name,
wxDynamicLibraryCategory cat)
{
#ifdef __UNIX__
if ( cat == wxDL_MODULE )
return name + GetDllExt();
else
return wxString(_T("lib")) + name + GetDllExt();
#else
return name + GetDllExt();
#endif
}
/*static*/
wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
wxPluginCategory cat)
{
wxString suffix;
if ( cat == wxDL_PLUGIN_GUI )
{
suffix = wxString::FromAscii(
#if defined(__WXMSW__)
"msw"
#elif defined(__WXGTK__)
"gtk"
#elif defined(__WXMGL__)
"mgl"
#elif defined(__WXMOTIF__)
"motif"
#elif defined(__WXOS2__)
"pm"
#elif defined(__WXX11__)
"x11"
#elif defined(__WXMAC__)
"mac"
#elif defined(__WXCOCOA__)
"cocoa"
#endif
);
#ifdef __WXUNIVERSAL__
suffix << _T("univ");
#endif
}
#if wxUSE_UNICODE
suffix << _T('u');
#endif
#ifdef __WXDEBUG__
suffix << _T('d');
#endif
if ( !suffix.empty() )
suffix = wxString(_T("_")) + suffix;
#ifdef __UNIX__
#if (wxMINOR_VERSION % 2) == 0
#define wxDLLVER(x,y,z) "-" #x "." #y
#else
#define wxDLLVER(x,y,z) "-" #x "." #y "." #z
#endif
#else
#if (wxMINOR_VERSION % 2) == 0
#define wxDLLVER(x,y,z) #x #y
#else
#define wxDLLVER(x,y,z) #x #y #z
#endif
#endif
suffix << wxString::FromAscii(wxDLLVER(wxMAJOR_VERSION, wxMINOR_VERSION,
wxRELEASE_NUMBER));
#undef wxDLLVER
return CanonicalizeName(name + suffix, wxDL_MODULE);
}
/*static*/
wxString wxDynamicLibrary::GetPluginsDirectory()
{
#ifdef __UNIX__
wxString format = wxGetInstallPrefix();
format << wxFILE_SEP_PATH
<< wxT("lib") << wxFILE_SEP_PATH
<< wxT("wx") << wxFILE_SEP_PATH
<< wxT("%i.%i");
wxString dir;
dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
return dir;
#else
return wxEmptyString;
#endif
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// wxPluginLibrary // wxPluginLibrary
@@ -723,23 +367,6 @@ bool wxPluginManager::UnloadLibrary(const wxString& libname)
return TRUE; return TRUE;
} }
#if WXWIN_COMPATIBILITY_2_2
wxPluginLibrary *wxPluginManager::GetObjectFromHandle(wxDllType handle)
{
for ( wxDLManifest::iterator i = ms_manifest->begin();
i != ms_manifest->end();
++i )
{
wxPluginLibrary * const lib = i->second;
if ( lib->GetLibHandle() == handle )
return lib;
}
return NULL;
}
#endif // WXWIN_COMPATIBILITY_2_2
// ------------------------ // ------------------------
// Class implementation // Class implementation
// ------------------------ // ------------------------
@@ -771,11 +398,29 @@ void wxPluginManager::Unload()
m_entry = NULL; m_entry = NULL;
} }
#if WXWIN_COMPATIBILITY_2_2
wxPluginLibrary *wxPluginManager::GetObjectFromHandle(wxDllType handle)
{
for ( wxDLManifest::iterator i = ms_manifest->begin();
i != ms_manifest->end();
++i )
{
wxPluginLibrary * const lib = i->second;
if ( lib->GetLibHandle() == handle )
return lib;
}
return NULL;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// wxDllLoader (all these methods are static) // wxDllLoader (all these methods are static)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#if WXWIN_COMPATIBILITY_2_2
wxDllType wxDllLoader::LoadLibrary(const wxString &name, bool *success) wxDllType wxDllLoader::LoadLibrary(const wxString &name, bool *success)
{ {
@@ -818,7 +463,158 @@ wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name, bool *success)
return p->GetSymbol(name, success); return p->GetSymbol(name, success);
} }
// ---------------------------------------------------------------------------
// Global variables
// ---------------------------------------------------------------------------
wxLibraries wxTheLibraries;
// ============================================================================
// implementation
// ============================================================================
// construct the full name from the base shared object name: adds a .dll
// suffix under Windows or .so under Unix
static wxString ConstructLibraryName(const wxString& basename)
{
wxString fullname;
fullname << basename << wxDllLoader::GetDllExt();
return fullname;
}
// ---------------------------------------------------------------------------
// wxLibrary (one instance per dynamic library)
// ---------------------------------------------------------------------------
wxLibrary::wxLibrary(wxDllType handle)
{
typedef wxClassInfo *(*t_get_first)(void);
t_get_first get_first;
m_handle = handle;
// Some system may use a local heap for library.
get_first = (t_get_first)GetSymbol(_T("wxGetClassFirst"));
// It is a wxWindows DLL.
if (get_first)
PrepareClasses(get_first());
}
wxLibrary::~wxLibrary()
{
if ( m_handle )
{
wxDllLoader::UnloadLibrary(m_handle);
}
}
wxObject *wxLibrary::CreateObject(const wxString& name)
{
wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
if (!info)
return NULL;
return info->CreateObject();
}
void wxLibrary::PrepareClasses(wxClassInfo *first)
{
// Index all class infos by their class name
wxClassInfo *info = first;
while (info)
{
if (info->m_className)
classTable.Put(info->m_className, (wxObject *)info);
info = info->m_next;
}
// Set base pointers for each wxClassInfo
info = first;
while (info)
{
if (info->GetBaseClassName1())
info->m_baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
if (info->GetBaseClassName2())
info->m_baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
info = info->m_next;
}
}
void *wxLibrary::GetSymbol(const wxString& symbname)
{
return wxDllLoader::GetSymbol(m_handle, symbname);
}
// ---------------------------------------------------------------------------
// wxLibraries (only one instance should normally exist)
// ---------------------------------------------------------------------------
wxLibraries::wxLibraries():m_loaded(wxKEY_STRING)
{
}
wxLibraries::~wxLibraries()
{
wxNode *node = m_loaded.First();
while (node) {
wxLibrary *lib = (wxLibrary *)node->Data();
delete lib;
node = node->Next();
}
}
wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
{
wxLibrary *lib;
wxClassInfo *old_sm_first;
wxNode *node = m_loaded.Find(name.GetData());
if (node != NULL)
return ((wxLibrary *)node->Data());
// If DLL shares data, this is necessary.
old_sm_first = wxClassInfo::sm_first;
wxClassInfo::sm_first = NULL;
wxString libname = ConstructLibraryName(name);
bool success = FALSE;
wxDllType handle = wxDllLoader::LoadLibrary(libname, &success);
if(success)
{
lib = new wxLibrary(handle);
wxClassInfo::sm_first = old_sm_first;
m_loaded.Append(name.GetData(), lib);
}
else
lib = NULL;
return lib;
}
wxObject *wxLibraries::CreateObject(const wxString& path)
{
wxNode *node = m_loaded.First();
wxObject *obj;
while (node) {
obj = ((wxLibrary *)node->Data())->CreateObject(path);
if (obj)
return obj;
node = node->Next();
}
return NULL;
}
#endif // WXWIN_COMPATIBILITY_2_2 #endif // WXWIN_COMPATIBILITY_2_2
#endif // wxUSE_DYNAMIC_LOADER #endif // wxUSE_DYNAMIC_LOADER