1998-08-04 17:49:26 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// 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
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#ifdef __GNUG__
|
|
|
|
#pragma implementation "dynlib.h"
|
|
|
|
#endif
|
|
|
|
|
1998-09-10 11:41:14 +00:00
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
|
|
#ifdef __BORLANDC__
|
|
|
|
#pragma hdrstop
|
|
|
|
#endif //__BORLANDC__
|
|
|
|
|
|
|
|
#ifndef WX_PRECOMP
|
|
|
|
#endif //WX_PRECOMP
|
|
|
|
|
1998-08-04 17:49:26 +00:00
|
|
|
#include <wx/dynlib.h>
|
|
|
|
#include <wx/filefn.h>
|
|
|
|
#include <wx/list.h>
|
|
|
|
#include <wx/string.h>
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// System dependent include
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
1998-08-18 15:28:46 +00:00
|
|
|
#ifdef __UNIX__
|
1998-08-04 17:49:26 +00:00
|
|
|
#include <dlfcn.h>
|
|
|
|
#endif
|
|
|
|
|
1998-08-05 17:12:43 +00:00
|
|
|
#ifdef __WINDOWS__
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
1998-09-08 22:27:12 +00:00
|
|
|
#ifdef LoadLibrary
|
|
|
|
#undef LoadLibrary
|
|
|
|
#endif
|
|
|
|
|
1998-08-04 17:49:26 +00:00
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// Global variables
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
wxLibraries wxTheLibraries;
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// wxLibrary (one instance per dynamic library
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
wxLibrary::wxLibrary(void *handle)
|
|
|
|
{
|
1998-09-01 17:17:05 +00:00
|
|
|
typedef wxClassInfo **(*t_get_first)(void);
|
|
|
|
t_get_first get_first;
|
1998-08-04 17:49:26 +00:00
|
|
|
|
|
|
|
m_handle = handle;
|
1998-09-01 17:17:05 +00:00
|
|
|
m_destroy = TRUE;
|
1998-08-04 17:49:26 +00:00
|
|
|
|
1998-09-01 17:17:05 +00:00
|
|
|
// 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());
|
1998-08-04 17:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
wxLibrary::~wxLibrary()
|
|
|
|
{
|
1998-09-01 17:17:05 +00:00
|
|
|
if (m_handle && m_destroy) {
|
1998-08-18 15:28:46 +00:00
|
|
|
#ifdef __UNIX__
|
1998-08-04 17:49:26 +00:00
|
|
|
dlclose(m_handle);
|
1998-08-05 17:12:43 +00:00
|
|
|
#endif
|
|
|
|
#ifdef __WINDOWS__
|
|
|
|
FreeLibrary((HMODULE)m_handle);
|
|
|
|
#endif
|
1998-08-04 17:49:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wxObject *wxLibrary::CreateObject(const wxString& name)
|
|
|
|
{
|
1998-09-01 17:17:05 +00:00
|
|
|
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)
|
|
|
|
{
|
1998-09-10 11:41:14 +00:00
|
|
|
if (info->m_className)
|
|
|
|
classTable.Put(info->m_className, (wxObject *)info);
|
|
|
|
info = info->m_next;
|
1998-09-01 17:17:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set base pointers for each wxClassInfo
|
|
|
|
info = *first;
|
|
|
|
while (info)
|
|
|
|
{
|
|
|
|
if (info->GetBaseClassName1())
|
1998-09-10 11:41:14 +00:00
|
|
|
info->m_baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
|
1998-09-01 17:17:05 +00:00
|
|
|
if (info->GetBaseClassName2())
|
1998-09-10 11:41:14 +00:00
|
|
|
info->m_baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
|
|
|
|
info = info->m_next;
|
1998-09-01 17:17:05 +00:00
|
|
|
}
|
|
|
|
*first = NULL;
|
1998-08-04 17:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void *wxLibrary::GetSymbol(const wxString& symbname)
|
|
|
|
{
|
1998-08-18 15:28:46 +00:00
|
|
|
#ifdef __UNIX__
|
1998-08-05 17:12:43 +00:00
|
|
|
return dlsym(m_handle, WXSTRINGCAST symbname);
|
1998-08-04 17:49:26 +00:00
|
|
|
#endif
|
1998-08-05 17:12:43 +00:00
|
|
|
#ifdef __WINDOWS__
|
1998-09-10 11:41:14 +00:00
|
|
|
return GetProcAddress((HINSTANCE) m_handle, WXSTRINGCAST symbname);
|
1998-08-05 17:12:43 +00:00
|
|
|
#endif
|
|
|
|
return NULL;
|
1998-08-04 17:49:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// wxLibraries (only one instance should normally exist)
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
wxLibraries::wxLibraries()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
wxString lib_name = name;
|
|
|
|
wxNode *node;
|
|
|
|
wxLibrary *lib;
|
|
|
|
|
|
|
|
if ( (node = m_loaded.Find(name.GetData())) )
|
|
|
|
return ((wxLibrary *)node->Data());
|
|
|
|
|
1998-09-01 17:17:05 +00:00
|
|
|
#if defined(__UNIX__)
|
1998-08-23 09:23:27 +00:00
|
|
|
lib_name.Prepend("./lib");
|
1998-08-04 17:49:26 +00:00
|
|
|
lib_name += ".so";
|
|
|
|
|
|
|
|
printf("lib_name = %s\n", WXSTRINGCAST lib_name);
|
|
|
|
|
1998-08-05 17:12:43 +00:00
|
|
|
void *handle = dlopen(WXSTRINGCAST lib_name, RTLD_LAZY);
|
1998-08-04 17:49:26 +00:00
|
|
|
|
1998-08-05 17:12:43 +00:00
|
|
|
if (!handle)
|
|
|
|
return NULL;
|
1998-09-01 17:17:05 +00:00
|
|
|
#elif defined(__WINDOWS__)
|
1998-08-04 17:49:26 +00:00
|
|
|
lib_name += ".dll";
|
|
|
|
|
1998-09-08 22:27:12 +00:00
|
|
|
#ifdef UNICODE
|
|
|
|
HMODULE handle = LoadLibraryW(lib_name);
|
|
|
|
#else
|
|
|
|
HMODULE handle = LoadLibraryA(lib_name);
|
|
|
|
#endif
|
1998-08-05 17:12:43 +00:00
|
|
|
if (!handle)
|
|
|
|
return NULL;
|
1998-09-01 17:17:05 +00:00
|
|
|
#else
|
|
|
|
return NULL;
|
1998-08-04 17:49:26 +00:00
|
|
|
#endif
|
1998-09-01 17:17:05 +00:00
|
|
|
|
1998-08-05 17:12:43 +00:00
|
|
|
lib = new wxLibrary((void *)handle);
|
1998-08-04 17:49:26 +00:00
|
|
|
|
|
|
|
m_loaded.Append(name.GetData(), lib);
|
|
|
|
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;
|
|
|
|
}
|