/Python/dynload_next.c
http://unladen-swallow.googlecode.com/ · C · 114 lines · 89 code · 8 blank · 17 comment · 11 complexity · 6df9b0ef3982aee5a6c721296010162e MD5 · raw file
- /* Support for dynamic loading of extension modules on Mac OS X
- ** All references to "NeXT" are for historical reasons.
- */
- #include "Python.h"
- #include "importdl.h"
- #include <mach-o/dyld.h>
- const struct filedescr _PyImport_DynLoadFiletab[] = {
- {".so", "rb", C_EXTENSION},
- {"module.so", "rb", C_EXTENSION},
- {0, 0}
- };
- /*
- ** Python modules are Mach-O MH_BUNDLE files. The best way to load these
- ** is each in a private namespace, so you can load, say, a module bar and a
- ** module foo.bar. If we load everything in the global namespace the two
- ** initbar() symbols will conflict.
- ** However, it seems some extension packages depend upon being able to access
- ** each others' global symbols. There seems to be no way to eat our cake and
- ** have it, so the USE_DYLD_GLOBAL_NAMESPACE define determines which behaviour
- ** you get.
- */
- #ifdef USE_DYLD_GLOBAL_NAMESPACE
- #define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR
- #else
- #define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
- NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
- #endif
- dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
- const char *pathname, FILE *fp)
- {
- dl_funcptr p = NULL;
- char funcname[258];
- NSObjectFileImageReturnCode rc;
- NSObjectFileImage image;
- NSModule newModule;
- NSSymbol theSym;
- const char *errString;
- char errBuf[512];
- PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname);
- #ifdef USE_DYLD_GLOBAL_NAMESPACE
- if (NSIsSymbolNameDefined(funcname)) {
- theSym = NSLookupAndBindSymbol(funcname);
- p = (dl_funcptr)NSAddressOfSymbol(theSym);
- return p;
- }
- #endif
- rc = NSCreateObjectFileImageFromFile(pathname, &image);
- switch(rc) {
- default:
- case NSObjectFileImageFailure:
- case NSObjectFileImageFormat:
- /* for these a message is printed on stderr by dyld */
- errString = "Can't create object file image";
- break;
- case NSObjectFileImageSuccess:
- errString = NULL;
- break;
- case NSObjectFileImageInappropriateFile:
- errString = "Inappropriate file type for dynamic loading";
- break;
- case NSObjectFileImageArch:
- errString = "Wrong CPU type in object file";
- break;
- case NSObjectFileImageAccess:
- errString = "Can't read object file (no access)";
- break;
- }
- if (errString == NULL) {
- newModule = NSLinkModule(image, pathname, LINKOPTIONS);
- if (newModule == NULL) {
- int errNo;
- const char *fileName, *moreErrorStr;
- NSLinkEditErrors c;
- NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
- PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
- fileName, moreErrorStr);
- errString = errBuf;
- }
- }
- if (errString != NULL) {
- PyErr_SetString(PyExc_ImportError, errString);
- return NULL;
- }
- #ifdef USE_DYLD_GLOBAL_NAMESPACE
- if (!NSIsSymbolNameDefined(funcname)) {
- /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
- /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
- PyErr_Format(PyExc_ImportError,
- "Loaded module does not contain symbol %.200s",
- funcname);
- return NULL;
- }
- theSym = NSLookupAndBindSymbol(funcname);
- #else
- theSym = NSLookupSymbolInModule(newModule, funcname);
- if ( theSym == NULL ) {
- /* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
- PyErr_Format(PyExc_ImportError,
- "Loaded module does not contain symbol %.200s",
- funcname);
- return NULL;
- }
- #endif
- p = (dl_funcptr)NSAddressOfSymbol(theSym);
- return p;
- }