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__
#define _WX_DYNLIB_H__
#ifdef __GNUG__
#pragma interface
#pragma interface
#endif
#include <wx/string.h>
#include <wx/list.h>
#include <wx/dynarray.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
#undef LoadLibrary
#undef LoadLibrary
#endif
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// wxLibrary
// ----------------------------------------------------------------------------
class wxLibrary: public wxObject {
protected:
void *m_handle;
bool m_destroy;
public:
wxHashTable classTable;
class wxLibrary : public wxObject
{
public:
wxHashTable classTable;
public:
wxLibrary(void *handle);
~wxLibrary(void);
public:
wxLibrary(void *handle);
~wxLibrary();
// Get a symbol from the dynamic library
void *GetSymbol(const wxString& symbname);
// Get a symbol from the dynamic library
void *GetSymbol(const wxString& symbname);
// Create the object whose classname is "name"
wxObject *CreateObject(const wxString& name);
// Create the object whose classname is "name"
wxObject *CreateObject(const wxString& name);
// Merge the symbols with the main symbols: WARNING! the library will not
// be unloaded.
void MergeWithSystem();
protected:
void PrepareClasses(wxClassInfo *first);
protected:
void PrepareClasses(wxClassInfo *first);
wxDllType m_handle;
};
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// wxLibraries
// ----------------------------------------------------------------------------
class wxLibraries {
protected:
wxList m_loaded;
public:
wxLibraries(void);
~wxLibraries(void);
class wxLibraries
{
public:
wxLibraries();
~wxLibraries();
wxLibrary *LoadLibrary(const wxString& name);
wxObject *CreateObject(const wxString& name);
// caller is responsible for deleting the returned pointer if !NULL
wxLibrary *LoadLibrary(const wxString& basename);
wxObject *CreateObject(const wxString& name);
protected:
wxList m_loaded;
};
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Global variables
// ----------------------------------------------------------------------------
extern wxLibraries wxTheLibraries;
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Interesting defines
// ----------------------------------------------------------------------------
#define WXDLL_ENTRY_FUNCTION() \
extern "C" wxClassInfo *wxGetClassFirst(); \
@ -70,4 +103,4 @@ wxClassInfo *wxGetClassFirst() { \
return wxClassInfo::GetFirst(); \
}
#endif
#endif // _WX_DYNLIB_H__

View File

@ -9,8 +9,16 @@
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "dynlib.h"
#pragma implementation "dynlib.h"
#endif
#include "wx/wxprec.h"
@ -19,29 +27,51 @@
#pragma hdrstop
#endif //__BORLANDC__
#ifndef WX_PRECOMP
#endif //WX_PRECOMP
// TODO should be done by configure
#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/filefn.h>
#include <wx/list.h>
#include <wx/string.h>
#include "wx/dynlib.h"
#include "wx/filefn.h"
#include "wx/intl.h"
#include "wx/log.h"
// ---------------------------------------------------------------------------
// System dependent include
// ---------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// conditional compilation
// ----------------------------------------------------------------------------
#if defined(__UNIX__)
#include <dlfcn.h>
#endif
#if defined(HAVE_DLOPEN)
#define wxDllOpen(lib) dlopen(lib, RTLD_LAZY)
#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__
#include <windows.h>
#endif
#ifdef LoadLibrary
#undef LoadLibrary
#endif
static inline void *wxDllGetSymbol(shl_t *handle, const char *name)
{
void *sym;
if ( shl_findsym(handle, name, TYPE_UNDEFINED, &sym) == 0 )
return sym;
else
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
@ -49,90 +79,117 @@
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);
t_get_first get_first;
wxString fullname(basename);
m_handle = handle;
m_destroy = TRUE;
#if defined(__UNIX__)
fullname << ".so";
#elif defined(__WINDOWS__)
fullname << ".dll";
#endif
// 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());
return fullname;
}
// ============================================================================
// 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()
{
if (m_handle && m_destroy) {
#if defined(__UNIX__)
dlclose(m_handle);
#endif
#ifdef __WINDOWS__
FreeLibrary((HMODULE)m_handle);
#endif
}
if ( m_handle )
{
wxDllClose(m_handle);
}
}
wxObject *wxLibrary::CreateObject(const wxString& name)
{
wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
if (!info)
return NULL;
if (!info)
return NULL;
return info->CreateObject();
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->GetNext();
}
// 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->GetNext();
}
// 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;
}
// 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)
{
#if defined(__UNIX__)
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 ) ;
c2pstr( (char*) symName ) ;
if ( FindSymbol( (CFragConnectionID) m_handle , symName , &symAddress , &symClass ) == noErr )
{
return symAddress ;
}
void *symbol = NULL; // return value
#if defined( __WXMAC__ )
Ptr symAddress ;
CFragSymbolClass symClass ;
Str255 symName ;
strcpy( (char*) symName , symbname ) ;
c2pstr( (char*) symName ) ;
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
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()
{
wxNode *node = m_loaded.First();
wxNode *node = m_loaded.First();
while (node) {
wxLibrary *lib = (wxLibrary *)node->Data();
delete lib;
while (node) {
wxLibrary *lib = (wxLibrary *)node->Data();
delete lib;
node = node->Next();
}
node = node->Next();
}
}
wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
{
wxString lib_name = name;
wxNode *node;
wxLibrary *lib;
wxClassInfo *old_sm_first;
wxNode *node;
wxLibrary *lib;
wxClassInfo *old_sm_first;
if ( (node = m_loaded.Find(name.GetData())) )
return ((wxLibrary *)node->Data());
if ( (node = m_loaded.Find(name.GetData())) )
return ((wxLibrary *)node->Data());
// If DLL shares data, this is necessary.
old_sm_first = wxClassInfo::sm_first;
wxClassInfo::sm_first = NULL;
// If DLL shares data, this is necessary.
old_sm_first = wxClassInfo::sm_first;
wxClassInfo::sm_first = NULL;
wxString lib_name = ConstructLibraryName(name);
#if defined(__UNIX__)
lib_name.Prepend("./lib");
lib_name += ".so";
// TODO use LD_LIBRARY_PATH!
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)
return NULL;
#elif defined(__WINDOWS__)
lib_name += ".dll";
if ( !handle )
{
wxLogSysError(_("Failed to load shared library '%s'"),
lib_name.c_str());
#ifdef UNICODE
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 ) ;
if (GetDiskFragment( &myFSSpec , 0 , kCFragGoesToEOF , "\p" , kPrivateCFragCopy , &handle , &myMainAddr ,
myErrName ) != noErr )
{
p2cstr( myErrName ) ;
wxASSERT_MSG( 1 , (char*)myErrName ) ;
return NULL ;
}
#else
return NULL;
#endif
return NULL;
}
lib = new wxLibrary((void *)handle);
lib = new wxLibrary(handle);
wxClassInfo::sm_first = old_sm_first;
wxClassInfo::sm_first = old_sm_first;
m_loaded.Append(name.GetData(), lib);
return lib;
m_loaded.Append(name.GetData(), lib);
return lib;
}
wxObject *wxLibraries::CreateObject(const wxString& path)
{
wxNode *node = m_loaded.First();
wxObject *obj;
wxNode *node = m_loaded.First();
wxObject *obj;
while (node) {
obj = ((wxLibrary *)node->Data())->CreateObject(path);
if (obj)
return obj;
while (node) {
obj = ((wxLibrary *)node->Data())->CreateObject(path);
if (obj)
return obj;
node = node->Next();
}
return NULL;
node = node->Next();
}
return NULL;
}