From 1948bb3274f2d39649c63b88f0e8781d0fc9b693 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Fri, 1 Aug 2003 21:12:40 +0000 Subject: [PATCH] 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 --- configure | 3 +- configure.in | 3 +- include/wx/chkconf.h | 10 + include/wx/dynlib.h | 273 +++++++++++------- include/wx/dynload.h | 202 +------------- src/common/dynlib.cpp | 616 ++++++++++++++++++++--------------------- src/common/dynload.cpp | 544 ++++++++++++------------------------ 7 files changed, 657 insertions(+), 994 deletions(-) diff --git a/configure b/configure index 17a782697f..ac87ff9522 100755 --- a/configure +++ b/configure @@ -32157,7 +32157,8 @@ if test "$wxUSE_DYNAMIC_LOADER" = "yes" ; then #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 diff --git a/configure.in b/configure.in index b4eb2b8b5f..f22e87cb7f 100644 --- a/configure.in +++ b/configure.in @@ -4714,7 +4714,8 @@ fi 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 diff --git a/include/wx/chkconf.h b/include/wx/chkconf.h index 7ac15bfa8b..8732dfc01b 100644 --- a/include/wx/chkconf.h +++ b/include/wx/chkconf.h @@ -851,6 +851,16 @@ # 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 diff --git a/include/wx/dynlib.h b/include/wx/dynlib.h index 7870ed3fe8..49b54d71db 100644 --- a/include/wx/dynlib.h +++ b/include/wx/dynlib.h @@ -18,58 +18,184 @@ #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 - typedef HMODULE wxDllType; +#define INCL_DOS +#include +#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 - typedef void *wxDllType; +#include +typedef void *wxDllType; #elif defined(HAVE_SHL_LOAD) -# include - typedef shl_t wxDllType; -#elif defined(__WINDOWS__) -# include // needed to get HMODULE - typedef HMODULE wxDllType; +#include +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 @@ -89,8 +215,8 @@ public: 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 @@ -102,7 +228,7 @@ public: 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 @@ -113,78 +239,23 @@ public: 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: @@ -231,6 +302,8 @@ protected: extern WXDLLIMPEXP_DATA_BASE(wxLibraries) wxTheLibraries; +#endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_DYNAMIC_LOADER + // ---------------------------------------------------------------------------- // Interesting defines // ---------------------------------------------------------------------------- diff --git a/include/wx/dynload.h b/include/wx/dynload.h index 0f69c8e709..7271c2ea8e 100644 --- a/include/wx/dynload.h +++ b/include/wx/dynload.h @@ -25,182 +25,16 @@ #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 -#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 -typedef void *wxDllType; -#elif defined(HAVE_SHL_LOAD) -#include -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 @@ -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 // _WX_DYNAMICLOADER_H__ diff --git a/src/common/dynlib.cpp b/src/common/dynlib.cpp index a452cb2c82..2d3ce5dfec 100644 --- a/src/common/dynlib.cpp +++ b/src/common/dynlib.cpp @@ -27,7 +27,7 @@ #pragma hdrstop #endif -#if wxUSE_DYNLIB_CLASS && !wxUSE_DYNAMIC_LOADER +#if wxUSE_DYNLIB_CLASS #if defined(__WINDOWS__) #include "wx/msw/private.h" @@ -37,210 +37,160 @@ #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 -# 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 +#include -// ============================================================================ -// 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; @@ -252,7 +202,7 @@ wxDllType wxDllLoader::LoadLibrary(const wxString & libname, bool *success) kCFragGoesToEOF, "\p", kPrivateCFragCopy, - &((CFragConnectionID)handle), + &m_handle, &myMainAddr, myErrName ) != noErr ) { @@ -260,85 +210,167 @@ wxDllType wxDllLoader::LoadLibrary(const wxString & libname, bool *success) 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); @@ -349,160 +381,104 @@ void *wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name, bool *su 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 -#include - -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 diff --git a/src/common/dynload.cpp b/src/common/dynload.cpp index fad9d7515a..a1e4bafe63 100644 --- a/src/common/dynload.cpp +++ b/src/common/dynload.cpp @@ -37,367 +37,11 @@ #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 @@ -723,23 +367,6 @@ bool wxPluginManager::UnloadLibrary(const wxString& libname) 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 // ------------------------ @@ -771,11 +398,29 @@ void wxPluginManager::Unload() 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) { @@ -818,7 +463,158 @@ wxDllLoader::GetSymbol(wxDllType dllHandle, 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 -- 2.45.2