]> 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 5f3f4fab75df3f5f9600cee10ac9c41eaa4d36af..3660cc21f81211392d5d2fddb3cf28be82a286d1 100644 (file)
         else
             return (void *)0;
     }
-#elif defined(__APPLE__) && defined(__UNIX__)
-char *dlopen(char *path, int mode /* mode is ignored */);
-void *dlsym(void *handle, char *symbol);
+#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);
-char *dlerror();
+const char *dlerror(void);
 
 #   define wxDllOpen(lib)                dlopen(lib.fn_str(), 0)
 #   define wxDllGetSymbol(handle, name)  dlsym(handle, name)
@@ -98,6 +104,8 @@ char *dlerror();
 #   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
@@ -214,10 +222,10 @@ wxDllLoader::GetProgramHandle(void)
 {
 #if defined( HAVE_DLOPEN ) && !defined(__EMX__)
    // optain handle for main program
-   return dlopen(NULL, RTLD_NOW/*RTLD_LAZY*/); 
+   return dlopen(NULL, RTLD_NOW/*RTLD_LAZY*/);
 #elif defined (HAVE_SHL_LOAD)
    // shl_findsymbol with NULL handle looks up in main program
-   return 0; 
+   return 0;
 #else
    wxFAIL_MSG( wxT("This method is not implemented under Windows or OS/2"));
    return 0;
@@ -235,19 +243,19 @@ 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] = "";
     wxDllOpen(zError, libname, handle);
 #else // !Mac
-    handle = wxDllOpen((char *)libname);
+    handle = wxDllOpen(libname);
 #endif // OS
 
     if ( !handle )
@@ -321,7 +329,7 @@ wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name)
     wxDllGetSymbol(dllHandle, symbol);
 #else
     // mb_str() is necessary in Unicode build
-    symbol = wxDllGetSymbol(dllHandle, (char *)name.mb_str());
+    symbol = wxDllGetSymbol(dllHandle, name.mb_str());
 #endif
 
     if ( !symbol )
@@ -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