#pragma implementation "dynlib.h"
#endif
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif //__BORLANDC__
+
+#ifndef WX_PRECOMP
+#endif //WX_PRECOMP
+
#include <wx/dynlib.h>
#include <wx/filefn.h>
#include <wx/list.h>
// System dependent include
// ---------------------------------------------------------------------------
-#ifdef linux
+#if defined(__UNIX__)
#include <dlfcn.h>
#endif
+#ifdef __WINDOWS__
+#include <windows.h>
+#endif
+
+#ifdef LoadLibrary
+#undef LoadLibrary
+#endif
+
// ---------------------------------------------------------------------------
// Global variables
// ---------------------------------------------------------------------------
wxLibrary::wxLibrary(void *handle)
{
- typedef wxClassLibrary *(*t_get_list)(void);
- t_get_list get_list;
+ typedef wxClassInfo *(*t_get_first)(void);
+ t_get_first get_first;
m_handle = handle;
+ m_destroy = TRUE;
- get_list = (t_get_list)GetSymbol("GetClassList");
- m_liblist = (*get_list)();
+ // 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) {
- typedef void (*t_free_list)(wxClassLibrary *);
- t_free_list free_list;
-
- free_list = (t_free_list) GetSymbol("FreeClassList");
- if (free_list != NULL)
- free_list(m_liblist);
- else
- delete m_liblist;
-
+ if (m_handle && m_destroy) {
+#if defined(__UNIX__)
dlclose(m_handle);
+#endif
+#ifdef __WINDOWS__
+ FreeLibrary((HMODULE)m_handle);
+#endif
}
}
wxObject *wxLibrary::CreateObject(const wxString& name)
{
- return m_liblist->CreateObject(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->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;
+ }
}
void *wxLibrary::GetSymbol(const wxString& symbname)
{
-#ifdef linux
- return dlsym(m_handle, symbname.GetData());
+#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 ;
+ }
#endif
+ return NULL;
}
// ---------------------------------------------------------------------------
wxString lib_name = name;
wxNode *node;
wxLibrary *lib;
+ wxClassInfo *old_sm_first;
if ( (node = m_loaded.Find(name.GetData())) )
return ((wxLibrary *)node->Data());
-#ifdef linux
+ // If DLL shares data, this is necessary.
+ old_sm_first = wxClassInfo::sm_first;
+ wxClassInfo::sm_first = NULL;
+
+#if defined(__UNIX__)
lib_name.Prepend("./lib");
lib_name += ".so";
printf("lib_name = %s\n", WXSTRINGCAST lib_name);
- void *handle = dlopen(lib_name.GetData(), RTLD_LAZY);
+ void *handle = dlopen(WXSTRINGCAST lib_name, RTLD_LAZY);
- printf("handle = %x\n", handle);
- lib = new wxLibrary(handle);
+ printf("error = %s\n", dlerror());
-#endif
-#ifdef __WINDOWS__
+ if (!handle)
+ return NULL;
+#elif defined(__WINDOWS__)
lib_name += ".dll";
+#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
+ lib = new wxLibrary((void *)handle);
+
+ wxClassInfo::sm_first = old_sm_first;
+
m_loaded.Append(name.GetData(), lib);
return lib;
}
while (node) {
obj = ((wxLibrary *)node->Data())->CreateObject(path);
- if (obj)
+ if (obj)
return obj;
node = node->Next();
}
return NULL;
}
-
-// ---------------------------------------------------------------------------
-// wxClassLibrary (this class is used to access the internal class)
-// ---------------------------------------------------------------------------
-
-wxClassLibrary::wxClassLibrary(void)
-{
-}
-
-wxClassLibrary::~wxClassLibrary(void)
-{
- uint i;
-
- for (i=0;i<m_list.Count();i++)
- delete (m_list[i]);
-}
-
-void wxClassLibrary::RegisterClass(wxClassInfo *class_info,
- const wxString& path)
-{
- wxClassLibInfo *info = new wxClassLibInfo;
-
- info->class_info = class_info;
- info->path = path;
- m_list.Add(info);
-}
-
-void wxClassLibrary::UnregisterClass(wxClassInfo *class_info)
-{
- uint i = 0;
-
- while (i < m_list.Count()) {
- if (m_list[i]->class_info == class_info) {
- delete (m_list[i]);
- m_list.Remove(i);
- return;
- }
- i++;
- }
-}
-
-bool wxClassLibrary::CreateObjects(const wxString& path,
- wxArrayClassInfo& objs)
-{
- wxClassLibInfo *info;
- uint i = 0;
-
- while (i < m_list.Count()) {
- info = m_list[i];
- if (wxMatchWild(path, info->path))
- objs.Add(info->class_info);
- i++;
- }
- return (i > 0);
-}
-
-bool wxClassLibrary::FetchInfos(const wxString& path,
- wxArrayClassLibInfo& infos)
-{
- wxClassLibInfo *info;
- uint i = 0;
-
- while (i < m_list.Count()) {
- info = m_list[i];
- if (wxMatchWild(path, info->path)) {
- wxClassLibInfo *inf = new wxClassLibInfo;
- *inf = *info;
- infos.Add(inf);
- }
- i++;
- }
- return (i > 0);
-}
-
-wxObject *wxClassLibrary::CreateObject(const wxString& path)
-{
- wxClassLibInfo *info;
- uint i = 0;
-
- while (i < m_list.Count()) {
- info = m_list[i];
- if (wxMatchWild(path, info->path))
- return info->class_info->CreateObject();
- i++;
- }
- return NULL;
-}