#define wxUSE_DYNAMIC_LOADER 1
_ACEOF
-elif test "$wxUSE_DYNLIB_CLASS" = "yes" ; then
+fi
+if test "$wxUSE_DYNLIB_CLASS" = "yes" ; then
cat >>confdefs.h <<\_ACEOF
#define wxUSE_DYNLIB_CLASS 1
_ACEOF
if test "$wxUSE_DYNAMIC_LOADER" = "yes" ; then
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)
fi
# endif
#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 */
#if wxUSE_GUI
#include "wx/setup.h"
-#if wxUSE_DYNAMIC_LOADER
-
-#include "wx/dynload.h" // Use the new (version of) wxDynamicLibrary instead
-
-#elif wxUSE_DYNLIB_CLASS
+#if wxUSE_DYNLIB_CLASS
#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...
-#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.
+// FIXME: can this go in private.h or something too??
#if defined(__WXPM__) || defined(__EMX__)
-# define INCL_DOS
-# include <os2.h>
- typedef HMODULE wxDllType;
+#define INCL_DOS
+#include <os2.h>
+#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;
+#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;
+#include <dl.h>
+typedef shl_t wxDllType;
#elif defined(__DARWIN__)
- typedef void *wxDllType;
+typedef void *wxDllType;
#elif defined(__WXMAC__)
- typedef void *wxDllType;
+typedef CFragConnectionID wxDllType;
#else
-# error "wxLibrary can't be compiled on this platform, sorry."
-#endif // OS
+#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.
-// 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"
+ 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
// ----------------------------------------------------------------------------
+#if WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
+
/*
wxDllLoader is a class providing an interface similar to unix's dlopen().
It is used by wxDynamicLibrary wxLibrary and manages the actual loading of
if success pointer is not NULL, it will be filled with TRUE if everything
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
LoadLibrary
itself or NULL if back linking is not supported by the current platform
(e.g. Win32).
*/
- static wxDllType GetProgramHandle();
+ static wxDllType GetProgramHandle() { return wxDynamicLibrary::GetProgramHandle(); }
/*
This function resolves a symbol in a loaded DLL, such as a
Returns the pointer to the symbol or NULL on error.
*/
- static void *GetSymbol(wxDllType dllHandle,
- const wxString &name,
- bool *success = NULL);
+ static void *GetSymbol(wxDllType dllHandle, const wxString &name, bool *success = 0);
// 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:
- // forbid construction of objects
- wxDllLoader();
- 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)
+ wxDllLoader(); // forbid construction of objects
};
+
// ----------------------------------------------------------------------------
// wxLibrary
// ----------------------------------------------------------------------------
+#include "wx/hash.h"
+
class WXDLLIMPEXP_BASE wxLibrary : public wxObject
{
public:
extern WXDLLIMPEXP_DATA_BASE(wxLibraries) wxTheLibraries;
+#endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER
+
// ----------------------------------------------------------------------------
// Interesting defines
// ----------------------------------------------------------------------------
#if wxUSE_DYNAMIC_LOADER
+#include "wx/dynlib.h"
#include "wx/hashmap.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;
-WX_DECLARE_EXPORTED_STRING_HASH_MAP(wxPluginLibrary *, wxDLManifest);
-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)
-};
+WX_DECLARE_STRING_HASH_MAP_WITH_DECL(wxPluginLibrary *, wxDLManifest,
+ class WXDLLIMPEXP_BASE);
+typedef wxDLManifest wxDLImports;
// ---------------------------------------------------------------------------
// wxPluginLibrary
};
-// ---------------------------------------------------------------------------
-// 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 // _WX_DYNAMICLOADER_H__
#pragma hdrstop
#endif
-#if wxUSE_DYNLIB_CLASS && !wxUSE_DYNAMIC_LOADER
+#if wxUSE_DYNLIB_CLASS
#if defined(__WINDOWS__)
#include "wx/msw/private.h"
#include "wx/filefn.h"
#include "wx/intl.h"
#include "wx/log.h"
+#include "wx/utils.h"
+#include "wx/filename.h" // for SplitPath()
#if defined(__WXMAC__)
#include "wx/mac/private.h"
#endif
-// ----------------------------------------------------------------------------
-// conditional compilation
-// ----------------------------------------------------------------------------
-#if defined(__WXPM__) || defined(__EMX__)
-# define INCL_DOS
-# 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
+// ============================================================================
+// implementation
+// ============================================================================
-static inline void *wxDllGetSymbol(shl_t handle, const wxString& name)
-{
- void *sym;
- if ( shl_findsym(&handle, name.mb_str(), TYPE_UNDEFINED, &sym) == 0 )
- return sym;
- else
- return 0;
-}
+#if defined(__DARWIN__)
+// ---------------------------------------------------------------------------
+// For Darwin/Mac OS X
+// supply the sun style dlopen functions in terms of Darwin NS*
+// ---------------------------------------------------------------------------
-#elif 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);
-
-# 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;
+#include <stdio.h>
+#include <mach-o/dyld.h>
-// ============================================================================
-// implementation
-// ============================================================================
+static char dl_last_error[1024];
-// 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)
+static
+void TranslateError(const char *path, int number)
{
- wxString fullname;
- fullname << basename << wxDllLoader::GetDllExt();
+ unsigned int index;
+ static char *OFIErrorStrings[] =
+ {
+ "%s(%d): Object Image Load Failure\n",
+ "%s(%d): Object Image Load Success\n",
+ "%s(%d): Not an recognisable object file\n",
+ "%s(%d): No valid architecture\n",
+ "%s(%d): Object image has an invalid format\n",
+ "%s(%d): Invalid access (permissions?)\n",
+ "%s(%d): Unknown error code from NSCreateObjectFileImageFromFile\n",
+ };
+#define NUM_OFI_ERRORS (sizeof(OFIErrorStrings) / sizeof(OFIErrorStrings[0]))
- return fullname;
+ index = number;
+ if (index > NUM_OFI_ERRORS - 1) {
+ index = NUM_OFI_ERRORS - 1;
+ }
+ sprintf(dl_last_error, OFIErrorStrings[index], path, number);
}
-// ---------------------------------------------------------------------------
-// wxLibrary (one instance per dynamic library)
-// ---------------------------------------------------------------------------
-
-wxLibrary::wxLibrary(wxDllType handle)
+const char *dlerror()
{
- 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());
+ return dl_last_error;
}
-wxLibrary::~wxLibrary()
+void *dlopen(const char *path, int WXUNUSED(mode) /* mode is ignored */)
{
- if ( m_handle )
+ int dyld_result;
+ NSObjectFileImage ofile;
+ NSModule handle = NULL;
+
+ dyld_result = NSCreateObjectFileImageFromFile(path, &ofile);
+ if (dyld_result != NSObjectFileImageSuccess)
{
- wxDllClose(m_handle);
+ TranslateError(path, dyld_result);
}
+ else
+ {
+ // NSLinkModule will cause the run to abort on any link error's
+ // not very friendly but the error recovery functionality is limited.
+ handle = NSLinkModule(ofile, path, NSLINKMODULE_OPTION_BINDNOW);
+ }
+
+ return handle;
}
-wxObject *wxLibrary::CreateObject(const wxString& name)
+int dlclose(void *handle)
{
- wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
-
- if (!info)
- return NULL;
-
- return info->CreateObject();
+ NSUnLinkModule( handle, NSUNLINKMODULE_OPTION_NONE);
+ return 0;
}
-void wxLibrary::PrepareClasses(wxClassInfo *first)
+void *dlsym(void *handle, const char *symbol)
{
- // Index all class infos by their class name
- wxClassInfo *info = first;
- while (info)
+ void *addr;
+
+ NSSymbol nsSymbol = NSLookupSymbolInModule( handle , symbol ) ;
+
+ if ( nsSymbol)
{
- if (info->m_className)
- classTable.Put(info->m_className, (wxObject *)info);
- info = info->m_next;
+ addr = NSAddressOfSymbol(nsSymbol);
}
-
- // Set base pointers for each wxClassInfo
- info = first;
- while (info)
+ else
{
- 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;
+ addr = NULL;
}
+ return addr;
}
-void *wxLibrary::GetSymbol(const wxString& symbname)
-{
- return wxDllLoader::GetSymbol(m_handle, symbname);
-}
+#endif // defined(__DARWIN__)
+
// ---------------------------------------------------------------------------
-// wxDllLoader
+// 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 wxString wxDllLoader::ms_dllext( _T(".dll") );
+ const wxChar *wxDynamicLibrary::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("") );
+ #if defined(__HPUX__)
+ const wxChar *wxDynamicLibrary::ms_dllext = _T(".sl");
+ #else
+ const wxChar *wxDynamicLibrary::ms_dllext = _T(".so");
+ #endif
#endif
-/* static */
-wxDllType wxDllLoader::GetProgramHandle()
+wxDllType wxDynamicLibrary::GetProgramHandle()
{
#if defined( HAVE_DLOPEN ) && !defined(__EMX__)
- // optain handle for main program
- return dlopen(NULL, RTLD_NOW/*RTLD_LAZY*/);
+ return dlopen(0, RTLD_LAZY);
#elif defined (HAVE_SHL_LOAD)
- // shl_findsymbol with NULL handle looks up in main program
- return 0;
+ return PROG_HANDLE;
#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)
+bool wxDynamicLibrary::Load(wxString libname, int flags)
{
- wxDllType handle;
- bool failed = FALSE;
+ 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();
+ }
+ }
-#if defined(__WXMAC__) && !defined(__UNIX__)
+ // 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;
kCFragGoesToEOF,
"\p",
kPrivateCFragCopy,
- &((CFragConnectionID)handle),
+ &m_handle,
&myMainAddr,
myErrName ) != noErr )
{
wxLogSysError( _("Failed to load shared library '%s' Error '%s'"),
libname.c_str(),
(char*)myErrName );
- handle = 0;
- failed = TRUE;
+ m_handle = 0;
}
#elif defined(__WXPM__) || defined(__EMX__)
- char zError[256] = "";
- wxDllOpen(zError, libname, handle);
+ 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
- handle = wxDllOpen(libname);
+ 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 ( !handle )
+ 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__)
-#ifdef HAVE_DLERROR
+#if wxUSE_UNICODE
+ wxWCharBuffer buffer = wxConvLocal.cMB2WC( dlerror() );
+ const wxChar *err = buffer;
+#else
const wxChar *err = dlerror();
+#endif
+
if( err )
- {
- failed = TRUE;
wxLogError( msg, err );
- }
#else
- failed = TRUE;
wxLogSysError( msg, libname.c_str() );
#endif
}
- if ( success )
- *success = !failed;
-
- return handle;
+ return IsLoaded();
}
-
-/* static */
-void wxDllLoader::UnloadLibrary(wxDllType handle)
+void wxDynamicLibrary::Unload()
{
- wxDllClose(handle);
+ 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;
+ }
}
-/* static */
-void *wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name, bool *success)
+void *wxDynamicLibrary::GetSymbol(const wxString &name, bool *success) const
{
- bool failed = FALSE;
+ wxCHECK_MSG( IsLoaded(), NULL,
+ _T("Can't load symbol from unloaded library") );
+
+ bool failed = FALSE;
void *symbol = 0;
-#if defined(__WXMAC__) && !defined(__UNIX__)
+#if defined(__WXMAC__) && !defined(__DARWIN__)
Ptr symAddress;
CFragSymbolClass symClass;
Str255 symName;
-
- wxMacStringToPascal( name.c_str() , symName ) ;
-
- if( FindSymbol( ((CFragConnectionID)dllHandle), symName, &symAddress, &symClass ) == noErr )
+#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__)
- wxDllGetSymbol(dllHandle, symbol);
+ DosQueryProcAddr( m_handle, 1L, name.c_str(), (PFN*)symbol );
-#else // Windows or Unix
+#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() );
- // 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());
+#error "runtime shared lib support not implemented"
#endif
-#endif // OS
-
if ( !symbol )
{
-#ifdef HAVE_DLERROR
+#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);
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)
+/*static*/
+wxString wxDynamicLibrary::CanonicalizeName(const wxString& name,
+ wxDynamicLibraryCategory cat)
{
- 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);
- }
+#ifdef __UNIX__
+ if ( cat == wxDL_MODULE )
+ return name + GetDllExt();
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;
+ return wxString(_T("lib")) + name + GetDllExt();
+#else
+ return name + GetDllExt();
+#endif
}
-#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 <mach-o/dyld.h>
-
-static char dl_last_error[1024];
-
-static
-void TranslateError(const char *path, int number)
+/*static*/
+wxString wxDynamicLibrary::CanonicalizePluginName(const wxString& name,
+ wxPluginCategory cat)
{
- unsigned int index;
- static char *OFIErrorStrings[] =
+ wxString suffix;
+ if ( cat == wxDL_PLUGIN_GUI )
{
- "%s(%d): Object Image Load Failure\n",
- "%s(%d): Object Image Load Success\n",
- "%s(%d): Not an recognisable object file\n",
- "%s(%d): No valid architecture\n",
- "%s(%d): Object image has an invalid format\n",
- "%s(%d): Invalid access (permissions?)\n",
- "%s(%d): Unknown error code from NSCreateObjectFileImageFromFile\n",
- };
-#define NUM_OFI_ERRORS (sizeof(OFIErrorStrings) / sizeof(OFIErrorStrings[0]))
+ 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
+ );
- index = number;
- if (index > NUM_OFI_ERRORS - 1) {
- index = NUM_OFI_ERRORS - 1;
+#ifdef __WXUNIVERSAL__
+ suffix << _T("univ");
+#endif
}
- sprintf(dl_last_error, OFIErrorStrings[index], path, number);
-}
+#if wxUSE_UNICODE
+ suffix << _T('u');
+#endif
+#ifdef __WXDEBUG__
+ suffix << _T('d');
+#endif
-const char *dlerror()
-{
- return dl_last_error;
-}
+ if ( !suffix.empty() )
+ suffix = wxString(_T("_")) + suffix;
-void *dlopen(const char *path, int WXUNUSED(mode) /* mode is ignored */)
-{
- int dyld_result;
- NSObjectFileImage ofile;
- NSModule handle = NULL;
-
- dyld_result = NSCreateObjectFileImageFromFile(path, &ofile);
- if (dyld_result != NSObjectFileImageSuccess)
- {
- TranslateError(path, dyld_result);
- }
- else
- {
- // NSLinkModule will cause the run to abort on any link error's
- // not very friendly but the error recovery functionality is limited.
- handle = NSLinkModule(ofile, path, NSLINKMODULE_OPTION_BINDNOW);
- }
+#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 handle;
+ return CanonicalizeName(name + suffix, wxDL_MODULE);
}
-
-int dlclose(void *handle)
+
+/*static*/
+wxString wxDynamicLibrary::GetPluginsDirectory()
{
- NSUnLinkModule( handle, NSUNLINKMODULE_OPTION_NONE);
- return 0;
+#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
}
-void *dlsym(void *handle, const char *symbol)
-{
- void *addr;
-
- NSSymbol nsSymbol = NSLookupSymbolInModule( handle , symbol ) ;
-
- if ( nsSymbol)
- {
- addr = NSAddressOfSymbol(nsSymbol);
- }
- else
- {
- addr = NULL;
- }
- return addr;
-}
-#endif // defined(__DARWIN__) && (wxUSE_DYNLIB_CLASS || wxUSE_DYNAMIC_LOADER)
+#endif // wxUSE_DYNLIB_CLASS
#include "wx/utils.h"
#endif
-#include "wx/filename.h" // for SplitPath()
#include "wx/strconv.h"
#include "wx/dynload.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
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
// ------------------------
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)
// ---------------------------------------------------------------------------
-#if WXWIN_COMPATIBILITY_2_2
wxDllType wxDllLoader::LoadLibrary(const wxString &name, bool *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 // wxUSE_DYNAMIC_LOADER