X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5fde6fcc9b551340a194ae4c726db5ab64b5c594..33754c4d83c59b7523a6da0c4fb21079cb60301c:/src/common/dynlib.cpp?ds=sidebyside diff --git a/src/common/dynlib.cpp b/src/common/dynlib.cpp index 5f3f4fab75..3660cc21f8 100644 --- a/src/common/dynlib.cpp +++ b/src/common/dynlib.cpp @@ -76,11 +76,17 @@ 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 +}; + +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