home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Python / dynload_next.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  4.3 KB  |  170 lines

  1.  
  2. /* Support for dynamic loading of extension modules */
  3.  
  4. #include "Python.h"
  5. #include "importdl.h"
  6.  
  7.  
  8. #ifdef WITH_DYLD
  9.  
  10. #define USE_DYLD
  11.  
  12. #include <mach-o/dyld.h>
  13.  
  14. #else /* WITH_DYLD */
  15.  
  16. #define USE_RLD
  17. /* Define this to 1 if you want be able to load ObjC modules as well:
  18.    it switches between two different way of loading modules on the NeXT,
  19.    one that directly interfaces with the dynamic loader (rld_load(), which
  20.    does not correctly load ObjC object files), and another that uses the
  21.    ObjC runtime (objc_loadModules()) to do the job.
  22.    You'll have to add ``-ObjC'' to the compiler flags if you set this to 1.
  23. */
  24. #define HANDLE_OBJC_MODULES 1
  25. #if HANDLE_OBJC_MODULES
  26. #include <objc/Object.h>
  27. #include <objc/objc-load.h>
  28. #endif
  29.  
  30. #include <mach-o/rld.h>
  31.  
  32. #endif /* WITH_DYLD */
  33.  
  34.  
  35. const struct filedescr _PyImport_DynLoadFiletab[] = {
  36.     {".so", "rb", C_EXTENSION},
  37.     {"module.so", "rb", C_EXTENSION},
  38.     {0, 0}
  39. };
  40.  
  41. dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
  42.                     const char *pathname, FILE *fp)
  43. {
  44.     dl_funcptr p = NULL;
  45.     char funcname[258];
  46.  
  47.     sprintf(funcname, "_init%.200s", shortname);
  48.  
  49. #ifdef USE_RLD
  50.     {
  51.         NXStream *errorStream;
  52.         struct mach_header *new_header;
  53.         const char *filenames[2];
  54.         long ret;
  55.         unsigned long ptr;
  56.  
  57.         errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
  58.         filenames[0] = pathname;
  59.         filenames[1] = NULL;
  60.  
  61. #if HANDLE_OBJC_MODULES
  62.  
  63. /* The following very bogus line of code ensures that
  64.    objc_msgSend, etc are linked into the binary.  Without
  65.    it, dynamic loading of a module that includes objective-c
  66.    method calls will fail with "undefined symbol _objc_msgSend()".
  67.    This remains true even in the presence of the -ObjC flag
  68.    to the compiler
  69. */
  70.  
  71.         [Object name];
  72.  
  73. /* objc_loadModules() dynamically loads the object files
  74.    indicated by the paths in filenames.  If there are any
  75.    errors generated during loading -- typically due to the
  76.    inability to find particular symbols -- an error message
  77.    will be written to errorStream.
  78.    It returns 0 if the module is successfully loaded, 1
  79.    otherwise.
  80. */
  81.  
  82.         ret = !objc_loadModules(filenames, errorStream,
  83.                     NULL, &new_header, NULL);
  84.  
  85. #else /* !HANDLE_OBJC_MODULES */
  86.  
  87.         ret = rld_load(errorStream, &new_header, 
  88.                 filenames, NULL);
  89.  
  90. #endif /* HANDLE_OBJC_MODULES */
  91.  
  92.         /* extract the error messages for the exception */
  93.         if(!ret) {
  94.             char *streamBuf;
  95.             int len, maxLen;
  96.  
  97.             NXPutc(errorStream, (char)0);
  98.  
  99.             NXGetMemoryBuffer(errorStream,
  100.                 &streamBuf, &len, &maxLen);
  101.             PyErr_SetString(PyExc_ImportError, streamBuf);
  102.         }
  103.  
  104.         if(ret && rld_lookup(errorStream, funcname, &ptr))
  105.             p = (dl_funcptr) ptr;
  106.  
  107.         NXCloseMemory(errorStream, NX_FREEBUFFER);
  108.  
  109.         if(!ret)
  110.             return NULL;
  111.     }
  112. #endif /* USE_RLD */
  113. #ifdef USE_DYLD
  114.     /* This is also NeXT-specific. However, frameworks (the new style
  115.     of shared library) and rld() can't be used in the same program;
  116.     instead, you have to use dyld, which is mostly unimplemented. */
  117.     {
  118.         NSObjectFileImageReturnCode rc;
  119.         NSObjectFileImage image;
  120.         NSModule newModule;
  121.         NSSymbol theSym;
  122.         void *symaddr;
  123.         const char *errString;
  124.     
  125.         rc = NSCreateObjectFileImageFromFile(pathname, &image);
  126.         switch(rc) {
  127.             default:
  128.             case NSObjectFileImageFailure:
  129.             NSObjectFileImageFormat:
  130.             /* for these a message is printed on stderr by dyld */
  131.             errString = "Can't create object file image";
  132.             break;
  133.             case NSObjectFileImageSuccess:
  134.             errString = NULL;
  135.             break;
  136.             case NSObjectFileImageInappropriateFile:
  137.             errString = "Inappropriate file type for dynamic loading";
  138.             break;
  139.             case NSObjectFileImageArch:
  140.             errString = "Wrong CPU type in object file";
  141.             break;
  142.             NSObjectFileImageAccess:
  143.             errString = "Can't read object file (no access)";
  144.             break;
  145.         }
  146.         if (errString == NULL) {
  147.             newModule = NSLinkModule(image, pathname, TRUE);
  148.             if (!newModule)
  149.                 errString = "Failure linking new module";
  150.         }
  151.         if (errString != NULL) {
  152.             PyErr_SetString(PyExc_ImportError, errString);
  153.             return NULL;
  154.         }
  155.         if (!NSIsSymbolNameDefined(funcname)) {
  156.             /* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
  157.             NSUnLinkModule(newModule, FALSE);
  158.             PyErr_Format(PyExc_ImportError,
  159.                      "Loaded module does not contain symbol %.200s",
  160.                      funcname);
  161.             return NULL;
  162.         }
  163.         theSym = NSLookupAndBindSymbol(funcname);
  164.         p = (dl_funcptr)NSAddressOfSymbol(theSym);
  165.      }
  166. #endif /* USE_DYLD */
  167.  
  168.     return p;
  169. }
  170.