]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/dynlib.cpp
modified configure to allow configuration of wxMotif under Darwin/Mac OS X
[wxWidgets.git] / src / common / dynlib.cpp
index 796231c31a802126e309007dba09f356c737742d..3660cc21f81211392d5d2fddb3cf28be82a286d1 100644 (file)
         else
             return (void *)0;
     }
-#elif defined(__APPLE__) && defined(__UNIX__)
+#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);
@@ -98,6 +104,8 @@ const char *dlerror(void);
 #   endif  // Win32/16
 #   define wxDllGetSymbol(handle, name)    ::GetProcAddress(handle, name)
 #   define wxDllClose                      ::FreeLibrary
+#elif defined(__WXMAC__)
+#   define wxDllClose(handle)               CloseConnection(&handle)
 #else
 #   error "Don't know how to load shared libraries on this platform."
 #endif // OS
@@ -166,7 +174,7 @@ void wxLibrary::PrepareClasses(wxClassInfo *first)
     {
         if (info->m_className)
             classTable.Put(info->m_className, (wxObject *)info);
-        info = info->GetNext();
+        info = (wxClassInfo *)info->GetNext();
     }
 
     // Set base pointers for each wxClassInfo
@@ -235,13 +243,13 @@ wxDllLoader::LoadLibrary(const wxString & libname, bool *success)
     Ptr myMainAddr ;
     Str255 myErrName ;
 
-    wxMacPathToFSSpec( libname , &myFSSpec ) ;
+    wxMacFilename2FSSpec( libname , &myFSSpec ) ;
     if (GetDiskFragment( &myFSSpec , 0 , kCFragGoesToEOF , "\p" , kPrivateCFragCopy , &handle , &myMainAddr ,
                 myErrName ) != noErr )
     {
         p2cstr( myErrName ) ;
-        wxASSERT_MSG( 1 , (char*)myErrName ) ;
-        return NULL ;
+        wxLogSysError( _("Failed to load shared library '%s' Error '%s'") , libname.c_str() , (char*)myErrName ) ;
+        handle = NULL ;
     }
 #elif defined(__WXPM__) || defined(__EMX__)
     char zError[256] = "";
@@ -363,7 +371,7 @@ wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
     if (node != NULL)
         return ((wxLibrary *)node->Data());
 #else // !OS/2
-    if ( (node = m_loaded.Find(name.GetData())) )
+    if ( (node = m_loaded.Find(name.GetData())) != NULL)
         return ((wxLibrary *)node->Data());
 #endif
     // If DLL shares data, this is necessary.
@@ -429,4 +437,100 @@ wxObject *wxLibraries::CreateObject(const wxString& path)
     return NULL;
 }
 
+#ifdef __DARWIN__
+// ---------------------------------------------------------------------------
+// For Darwin/Mac OS X
+//   supply the sun style dlopen functions in terms of Darwin NS*
+// ---------------------------------------------------------------------------
+
+extern "C" {
+#import <mach-o/dyld.h>
+};
+
+enum dyldErrorSource
+{
+    OFImage,
+};
+
+static char dl_last_error[1024];
+
+static
+void TranslateError(const char *path, enum dyldErrorSource type, int number)
+{
+    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]))
+
+    switch (type)
+    {
+     case OFImage:
+        index = number;
+        if (index > NUM_OFI_ERRORS - 1) {
+            index = NUM_OFI_ERRORS - 1;
+        }
+        sprintf(dl_last_error, OFIErrorStrings[index], path, number);
+        break;
+        
+     default:
+        sprintf(dl_last_error, "%s(%d): Totally unknown error type %d\n",
+                path, number, type);
+        break;
+    }
+}
+
+const char *dlerror()
+{
+    return dl_last_error;
+}
+
+void *dlopen(const char *path, int mode /* mode is ignored */)
+{
+    int dyld_result;
+    NSObjectFileImage ofile;
+    NSModule handle = NULL;
+
+    dyld_result = NSCreateObjectFileImageFromFile(path, &ofile);
+    if (dyld_result != NSObjectFileImageSuccess)
+    {
+       TranslateError(path, OFImage, 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, TRUE);
+    }
+
+    return handle;
+}
+
+int dlclose(void *handle) /* stub only */
+{
+    return 0;
+}
+
+void *dlsym(void *handle, const char *symbol)
+{
+    void *addr;
+
+    if (NSIsSymbolNameDefined(symbol)) {
+       addr = NSAddressOfSymbol(NSLookupAndBindSymbol(symbol));
+    }
+    else {
+       addr = NULL;
+    }
+    return addr;
+}
+
+#endif // __DARWIN__
+
 #endif // wxUSE_DYNLIB_CLASS