HP-UX support added

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1751 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-02-22 19:42:45 +00:00
parent f76f940bce
commit 7b0bfbb256
2 changed files with 259 additions and 179 deletions

View File

@@ -1,68 +1,101 @@
/////////////////////////////////////////////////////////////////////////////
// Name: dynlib.cpp
// Purpose: Dynamic library management
// Author: Guilhem Lavaux
// Modified by:
// Created: 20/07/98
// RCS-ID: $Id$
// Copyright: (c) Guilhem Lavaux
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_DYNLIB_H__ #ifndef _WX_DYNLIB_H__
#define _WX_DYNLIB_H__ #define _WX_DYNLIB_H__
#ifdef __GNUG__ #ifdef __GNUG__
#pragma interface #pragma interface
#endif #endif
#include <wx/string.h> #include <wx/string.h>
#include <wx/list.h> #include <wx/list.h>
#include <wx/dynarray.h>
#include <wx/hash.h> #include <wx/hash.h>
#if defined(HAVE_DLOPEN)
#include <dlfcn.h>
typedef void *wxDllType;
#elif defined(HAVE_SHLLOAD)
#include <dl.h>
typedef void *wxDllType;
#elif defined(__WINDOWS__)
#include <windows.h>
typedef HMODULE wxDllType;
#elif defined(__WXMAC__)
typedef CFragConnectionID wxDllType;
#else
#error "wxLibrary can't be compiled on this platform, sorry."
#endif // OS
// defined in windows.h
#ifdef LoadLibrary #ifdef LoadLibrary
#undef LoadLibrary #undef LoadLibrary
#endif #endif
// --------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxLibrary // wxLibrary
// ----------------------------------------------------------------------------
class wxLibrary: public wxObject { class wxLibrary : public wxObject
protected: {
void *m_handle; public:
bool m_destroy; wxHashTable classTable;
public:
wxHashTable classTable;
public: public:
wxLibrary(void *handle); wxLibrary(void *handle);
~wxLibrary(void); ~wxLibrary();
// Get a symbol from the dynamic library // Get a symbol from the dynamic library
void *GetSymbol(const wxString& symbname); void *GetSymbol(const wxString& symbname);
// Create the object whose classname is "name" // Create the object whose classname is "name"
wxObject *CreateObject(const wxString& name); wxObject *CreateObject(const wxString& name);
// Merge the symbols with the main symbols: WARNING! the library will not protected:
// be unloaded. void PrepareClasses(wxClassInfo *first);
void MergeWithSystem();
protected: wxDllType m_handle;
void PrepareClasses(wxClassInfo *first);
}; };
// --------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxLibraries // wxLibraries
// ----------------------------------------------------------------------------
class wxLibraries { class wxLibraries
protected: {
wxList m_loaded; public:
public: wxLibraries();
wxLibraries(void); ~wxLibraries();
~wxLibraries(void);
wxLibrary *LoadLibrary(const wxString& name); // caller is responsible for deleting the returned pointer if !NULL
wxObject *CreateObject(const wxString& name); wxLibrary *LoadLibrary(const wxString& basename);
wxObject *CreateObject(const wxString& name);
protected:
wxList m_loaded;
}; };
// --------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Global variables // Global variables
// ----------------------------------------------------------------------------
extern wxLibraries wxTheLibraries; extern wxLibraries wxTheLibraries;
// --------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Interesting defines // Interesting defines
// ----------------------------------------------------------------------------
#define WXDLL_ENTRY_FUNCTION() \ #define WXDLL_ENTRY_FUNCTION() \
extern "C" wxClassInfo *wxGetClassFirst(); \ extern "C" wxClassInfo *wxGetClassFirst(); \
@@ -70,4 +103,4 @@ wxClassInfo *wxGetClassFirst() { \
return wxClassInfo::GetFirst(); \ return wxClassInfo::GetFirst(); \
} }
#endif #endif // _WX_DYNLIB_H__

View File

@@ -9,8 +9,16 @@
// Licence: wxWindows license // Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "dynlib.h" #pragma implementation "dynlib.h"
#endif #endif
#include "wx/wxprec.h" #include "wx/wxprec.h"
@@ -19,29 +27,51 @@
#pragma hdrstop #pragma hdrstop
#endif //__BORLANDC__ #endif //__BORLANDC__
#ifndef WX_PRECOMP // TODO should be done by configure
#endif //WX_PRECOMP #if defined(__UNIX__) && !(defined(HAVE_DLOPEN) || defined(HAVE_SHLLOAD))
#if defined(__LINUX__) || defined(__SOLARIS__) || defined(__SUNOS__)
#ifndef HAVE_DLOPEN
#define HAVE_DLOPEN
#endif
#elif defined(__HPUX__)
#ifndef HAVE_SHLLOAD
#define HAVE_SHLLOAD
#endif
#endif // Unix flavour
#endif // !Unix or already have some HAVE_xxx defined
#include <wx/dynlib.h> #include "wx/dynlib.h"
#include <wx/filefn.h> #include "wx/filefn.h"
#include <wx/list.h> #include "wx/intl.h"
#include <wx/string.h> #include "wx/log.h"
// --------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// System dependent include // conditional compilation
// --------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if defined(__UNIX__) #if defined(HAVE_DLOPEN)
#include <dlfcn.h> #define wxDllOpen(lib) dlopen(lib, RTLD_LAZY)
#endif #define wxDllGetSymbol(handle, name) dlsym(handle, (char *)name)
#define wxDllClose dlclose
#elif defined(HAVE_SHLLOAD)
#define wxDllOpen(lib) shl_open(lib, BIND_DEFERRED, 0)
#define wxDllClose shl_unload
#ifdef __WINDOWS__ static inline void *wxDllGetSymbol(shl_t *handle, const char *name)
#include <windows.h> {
#endif void *sym;
if ( shl_findsym(handle, name, TYPE_UNDEFINED, &sym) == 0 )
#ifdef LoadLibrary return sym;
#undef LoadLibrary else
#endif return (void *)0;
}
#elif defined(__WINDOWS__)
#define wxDllOpen(lib) ::LoadLibrary(lib)
#define wxDllGetSymbol(handle, name) ::GetProcAddress(handle, name)
#define wxDllClose ::FreeLibrary
#else
#error "Don't know how to load shared libraries on this platform."
#endif // OS
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Global variables // Global variables
@@ -49,90 +79,117 @@
wxLibraries wxTheLibraries; wxLibraries wxTheLibraries;
// --------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxLibrary (one instance per dynamic library // private functions
// --------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxLibrary::wxLibrary(void *handle) // 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)
{ {
typedef wxClassInfo *(*t_get_first)(void); wxString fullname(basename);
t_get_first get_first;
m_handle = handle; #if defined(__UNIX__)
m_destroy = TRUE; fullname << ".so";
#elif defined(__WINDOWS__)
fullname << ".dll";
#endif
// Some system may use a local heap for library. return fullname;
get_first = (t_get_first)GetSymbol("wxGetClassFirst"); }
// It is a wxWindows DLL.
if (get_first) // ============================================================================
PrepareClasses(get_first()); // implementation
// ============================================================================
// ---------------------------------------------------------------------------
// 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("wxGetClassFirst");
// It is a wxWindows DLL.
if (get_first)
PrepareClasses(get_first());
} }
wxLibrary::~wxLibrary() wxLibrary::~wxLibrary()
{ {
if (m_handle && m_destroy) { if ( m_handle )
#if defined(__UNIX__) {
dlclose(m_handle); wxDllClose(m_handle);
#endif }
#ifdef __WINDOWS__
FreeLibrary((HMODULE)m_handle);
#endif
}
} }
wxObject *wxLibrary::CreateObject(const wxString& name) wxObject *wxLibrary::CreateObject(const wxString& name)
{ {
wxClassInfo *info = (wxClassInfo *)classTable.Get(name); wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
if (!info) if (!info)
return NULL; return NULL;
return info->CreateObject(); return info->CreateObject();
} }
void wxLibrary::PrepareClasses(wxClassInfo *first) void wxLibrary::PrepareClasses(wxClassInfo *first)
{ {
// Index all class infos by their class name // Index all class infos by their class name
wxClassInfo *info = first; wxClassInfo *info = first;
while (info) while (info)
{ {
if (info->m_className) if (info->m_className)
classTable.Put(info->m_className, (wxObject *)info); classTable.Put(info->m_className, (wxObject *)info);
info = info->GetNext(); info = info->GetNext();
} }
// Set base pointers for each wxClassInfo // Set base pointers for each wxClassInfo
info = first; info = first;
while (info) while (info)
{ {
if (info->GetBaseClassName1()) if (info->GetBaseClassName1())
info->m_baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1()); info->m_baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
if (info->GetBaseClassName2()) if (info->GetBaseClassName2())
info->m_baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2()); info->m_baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
info = info->m_next; info = info->m_next;
} }
} }
void *wxLibrary::GetSymbol(const wxString& symbname) void *wxLibrary::GetSymbol(const wxString& symbname)
{ {
#if defined(__UNIX__) void *symbol = NULL; // return value
return dlsym(m_handle, WXSTRINGCAST symbname);
#elif defined( __WINDOWS__ )
return GetProcAddress((HINSTANCE) m_handle, WXSTRINGCAST symbname);
#elif defined( __WXMAC__ )
Ptr symAddress ;
CFragSymbolClass symClass ;
Str255 symName ;
strcpy( (char*) symName , symbname ) ; #if defined( __WXMAC__ )
c2pstr( (char*) symName ) ; Ptr symAddress ;
CFragSymbolClass symClass ;
Str255 symName ;
if ( FindSymbol( (CFragConnectionID) m_handle , symName , &symAddress , &symClass ) == noErr ) strcpy( (char*) symName , symbname ) ;
{ c2pstr( (char*) symName ) ;
return symAddress ;
} if ( FindSymbol( m_handle , symName , &symAddress , &symClass ) == noErr )
{
symbol = (void *)symAddress ;
}
#else
// VZ: hmm... why is WXSTRINGCAST needed? if it's really modified, we
// should make a copy of it
symbol = wxDllGetSymbol(m_handle, WXSTRINGCAST symbname);
#endif #endif
return NULL;
if ( !symbol )
{
wxLogSysError(_("Couldn't find symbol '%s' in a dynamic library"),
symbname.c_str());
}
return symbol;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -145,93 +202,83 @@ wxLibraries::wxLibraries()
wxLibraries::~wxLibraries() wxLibraries::~wxLibraries()
{ {
wxNode *node = m_loaded.First(); wxNode *node = m_loaded.First();
while (node) { while (node) {
wxLibrary *lib = (wxLibrary *)node->Data(); wxLibrary *lib = (wxLibrary *)node->Data();
delete lib; delete lib;
node = node->Next(); node = node->Next();
} }
} }
wxLibrary *wxLibraries::LoadLibrary(const wxString& name) wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
{ {
wxString lib_name = name; wxNode *node;
wxNode *node; wxLibrary *lib;
wxLibrary *lib; wxClassInfo *old_sm_first;
wxClassInfo *old_sm_first;
if ( (node = m_loaded.Find(name.GetData())) ) if ( (node = m_loaded.Find(name.GetData())) )
return ((wxLibrary *)node->Data()); return ((wxLibrary *)node->Data());
// If DLL shares data, this is necessary. // If DLL shares data, this is necessary.
old_sm_first = wxClassInfo::sm_first; old_sm_first = wxClassInfo::sm_first;
wxClassInfo::sm_first = NULL; wxClassInfo::sm_first = NULL;
wxString lib_name = ConstructLibraryName(name);
#if defined(__UNIX__) #if defined(__UNIX__)
lib_name.Prepend("./lib"); // TODO use LD_LIBRARY_PATH!
lib_name += ".so"; lib_name.Prepend("/lib");
#endif // __UNIX__
printf("lib_name = %s\n", WXSTRINGCAST lib_name); wxDllType handle ;
void *handle = dlopen(WXSTRINGCAST lib_name, RTLD_LAZY); #if defined(__WXMAC__)
FSSpec myFSSpec ;
Ptr myMainAddr ;
Str255 myErrName ;
printf("error = %s\n", dlerror()); wxMacPathToFSSpec( lib_name , &myFSSpec ) ;
if (GetDiskFragment( &myFSSpec , 0 , kCFragGoesToEOF , "\p" , kPrivateCFragCopy , &handle , &myMainAddr ,
myErrName ) != noErr )
{
p2cstr( myErrName ) ;
wxASSERT_MSG( 1 , (char*)myErrName ) ;
return NULL ;
}
#else // !Mac
handle = wxDllOpen(lib_name);
#endif // OS
if (!handle) if ( !handle )
return NULL; {
#elif defined(__WINDOWS__) wxLogSysError(_("Failed to load shared library '%s'"),
lib_name += ".dll"; lib_name.c_str());
#ifdef UNICODE return NULL;
HMODULE handle = LoadLibraryW(lib_name); }
#else
#ifdef __WIN16__
HMODULE handle = ::LoadLibrary(lib_name);
#else
HMODULE handle = LoadLibraryA(lib_name);
#endif
#endif
if (!handle)
return NULL;
#elif defined(__WXMAC__)
FSSpec myFSSpec ;
CFragConnectionID handle ;
Ptr myMainAddr ;
Str255 myErrName ;
wxMacPathToFSSpec( lib_name , &myFSSpec ) ; lib = new wxLibrary(handle);
if (GetDiskFragment( &myFSSpec , 0 , kCFragGoesToEOF , "\p" , kPrivateCFragCopy , &handle , &myMainAddr ,
myErrName ) != noErr )
{
p2cstr( myErrName ) ;
wxASSERT_MSG( 1 , (char*)myErrName ) ;
return NULL ;
}
#else
return NULL;
#endif
lib = new wxLibrary((void *)handle); wxClassInfo::sm_first = old_sm_first;
wxClassInfo::sm_first = old_sm_first; m_loaded.Append(name.GetData(), lib);
m_loaded.Append(name.GetData(), lib); return lib;
return lib;
} }
wxObject *wxLibraries::CreateObject(const wxString& path) wxObject *wxLibraries::CreateObject(const wxString& path)
{ {
wxNode *node = m_loaded.First(); wxNode *node = m_loaded.First();
wxObject *obj; wxObject *obj;
while (node) { while (node) {
obj = ((wxLibrary *)node->Data())->CreateObject(path); obj = ((wxLibrary *)node->Data())->CreateObject(path);
if (obj) if (obj)
return obj; return obj;
node = node->Next(); node = node->Next();
} }
return NULL; return NULL;
} }