Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r1900 - in trunk: Core Core/Util Engine/Factory


Chronological Thread 
  • From: boulos@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [Manta] r1900 - in trunk: Core Core/Util Engine/Factory
  • Date: Mon, 3 Dec 2007 17:53:41 -0700 (MST)

Author: boulos
Date: Mon Dec  3 17:53:39 2007
New Revision: 1900

Added:
   trunk/Core/Util/Plugin.h
Modified:
   trunk/Core/CMakeLists.txt
   trunk/Engine/Factory/Factory.cc
Log:
Core/Util/Plugin.h

 Porting my cross platform Plugin loader from galileo. This should let
 us run on older Apple versions (Leopard seems to have deprecated the
 dyld NSAddImage stuff), various unixes, and Win32.

Core/CMakeLists.txt

 Adding Plugin.h to sources

Engine/Factory/Factory.cc

 Using new Plugin code for readMOScene and readMOStack. This needs to
 be tested on more systems as Plugin loading code is notoriously
 system dependent (so I've kept the old code in an if/else
 block). Going to test Win32 and Linux now.


Modified: trunk/Core/CMakeLists.txt
==============================================================================
--- trunk/Core/CMakeLists.txt   (original)
+++ trunk/Core/CMakeLists.txt   Mon Dec  3 17:53:39 2007
@@ -156,6 +156,7 @@
      Util/LargeFile.h
      Util/LargeFile.cc
      Util/MemoryPool.h
+     Util/Plugin.h
      Util/Preprocessor.h
      Util/PriorityQueue.h
      Util/rgbe.h

Added: trunk/Core/Util/Plugin.h
==============================================================================
--- (empty file)
+++ trunk/Core/Util/Plugin.h    Mon Dec  3 17:53:39 2007
@@ -0,0 +1,98 @@
+#ifndef _MANTA_CORE_UTIL_PLUGIN_H_
+#define _MANTA_CORE_UTIL_PLUGIN_H_
+
+#include <string.h>
+#include <string>
+#include <iostream>
+#ifdef WIN32
+#include <windows.h>
+#elif defined(__APPLE__)
+// NOTE(boulos): We should also not take this path but use dlfcn if
+// we're on Leopard (as apparently dyld is now deprecated)
+#include <mach-o/dyld.h>
+#else
+#include <dlfcn.h>
+#endif
+
+#include <Core/Exceptions/InputError.h>
+
+namespace Manta {
+  template <class T>
+  class Plugin {
+  public:
+    Plugin() {
+      memset(name, 0, sizeof(name));
+    }
+    Plugin(const char* plugin_name) {
+      memset(name, 0, sizeof(name));
+      strncpy(name, plugin_name, sizeof(name));
+      // load the shared object
+#ifdef WIN32
+      object = LoadLibrary(name);
+      if (!object)
+        throw InputError("Can't open plugin: " + std::string(name));
+
+#elif defined(__APPLE__)
+      object = NSAddImage(name, NSADDIMAGE_OPTION_NONE);
+      if (!object)
+        throw InputError("Can't open plugin: " + std::string(name));
+#else
+      object = dlopen(name, RTLD_NOW);
+      if (!object)
+        throw InputError("Can't open plugin : " + std::string(name) + ", 
dlerror = " + std::string(dlerror()));
+#endif
+    }
+
+    ~Plugin() {
+#ifdef WIN32
+      if (object)
+        FreeLibrary(object);
+#elif defined(__APPLE__)
+      // don't free the const mach_header*
+#else
+      if (object)
+        dlclose(object);
+#endif
+    }
+
+    bool loadSymbol(const char* symbol) {
+      void* address = NULL;
+
+#ifdef WIN32
+      address = (void*)GetProcAddress(object, symbol);
+#elif defined(__APPLE__)
+      // NOTE(boulos): Thanks to incredible smarts, the symbols in
+      // Mach files get an _ in front of them...
+      char underscored[1024];
+      sprintf(underscored, "_%s", symbol);
+      NSSymbol nssym = NSLookupSymbolInImage(object,
+                                             underscored,
+                                             
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW);
+      address = NSAddressOfSymbol(nssym);
+#else
+      address = (void*)dlsym(object, symbol);
+#endif
+      if (!address) {
+        throw InputError("Failed to find symbol " + std::string(symbol) + " 
in Plugin " + std::string(name) + "\n");
+        return false;
+      }
+
+      function = (T)address;
+      return true;
+    }
+
+    char name[1024];
+#ifdef WIN32
+    typedef HMODULE DSOType;
+#elif defined(__APPLE__)
+    typedef const struct mach_header* DSOType;
+#else // Unix systems
+    typedef void* DSOType;
+#endif
+    DSOType object;
+    T function;
+
+  };
+} // end namespace Manta
+
+#endif // _MANTA_CORE_UTIL_PLUGIN_H_

Modified: trunk/Engine/Factory/Factory.cc
==============================================================================
--- trunk/Engine/Factory/Factory.cc     (original)
+++ trunk/Engine/Factory/Factory.cc     Mon Dec  3 17:53:39 2007
@@ -36,6 +36,7 @@
 #include <Core/Persistent/Archive.h>
 #include <Core/Persistent/ArchiveElement.h>
 #include <Core/Util/Args.h>
+#include <Core/Util/Plugin.h>
 #include <Engine/Factory/RegisterKnownComponents.h>
 #include <Interface/Context.h>
 #include <Interface/MantaInterface.h>
@@ -45,10 +46,11 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <dlfcn.h>
+//#include <dlfcn.h>
 #include <stdio.h>
 
 
+
 using namespace Manta;
 
 Factory::~Factory()
@@ -67,7 +69,7 @@
   ImageDisplayMapType::const_iterator iter = imageDisplays.find(name);
   if(iter == imageDisplays.end())
     throw UnknownComponent( "Image display not found", spec );
-  
+
   return (*iter->second)(args);
 }
 
@@ -76,7 +78,7 @@
   ImageDisplayMapType::iterator iter = imageDisplays.find(name);
   if(iter != imageDisplays.end())
     throw IllegalValue<string>("Duplicate ImageDisplay component", name);
-  imageDisplays[name] = fun;  
+  imageDisplays[name] = fun;
 }
 
 Factory::listType Factory::listImageDisplays() const
@@ -94,11 +96,11 @@
   string name;
   vector<string> args;
   parseSpec(spec, name, args);
-  
+
   ImageCreatorMapType::const_iterator iter = imageCreators.find(name);
   if(iter == imageCreators.end())
     return 0;
-  
+
   ImageCreator creator = iter->second;
 
   // Create a static method callback.
@@ -444,7 +446,7 @@
   for(vector<string>::iterator dir = dirs.begin(); dir != dirs.end(); dir++){
 
     fullname = *dir + "/" + name;
-    
+
     // Check to see if the file exists.
     struct stat statbuf;
     if(stat(fullname.c_str(), &statbuf) == 0){
@@ -455,7 +457,7 @@
   Archive* archive = Archive::openForReading(fullname);
   if(!archive)
     throw InputError("Could not open Archive: " + fullname);
-  
+
   ArchiveElement* root = archive->getRoot();
   if(!root)
     throw InputError("Cannot find scene in file: " + fullname);
@@ -464,7 +466,7 @@
   if(!scene)
     throw InternalError("Error reading file: " + fullname);
   return scene;
-}  
+}
 
 Scene* Factory::readMOScene(const string& name, const vector<string>& args,
                             bool printErrors) const
@@ -475,7 +477,7 @@
   for(vector<string>::iterator dir = dirs.begin(); dir != dirs.end(); dir++){
 
     fullname = *dir + "/" + name;
-    
+
     // Check to see if the file exists.
     struct stat statbuf;
     if(stat(fullname.c_str(), &statbuf) == 0){
@@ -483,6 +485,22 @@
     }
   }
 
+#if 1
+  typedef Scene* (*MakerType)(const ReadContext&, const vector<string>&);
+  Plugin<MakerType> scene_file(fullname.c_str());
+
+  if (!scene_file.loadSymbol("make_scene")) {
+    return NULL;
+  }
+
+  MakerType make_scene = scene_file.function;
+  // Call the make_scene function.
+  ReadContext context(manta_interface);
+  Scene* scene=(*make_scene)(context, args);
+  if(!scene){
+    throw InputError( "make_scene returned null" );
+  }
+#else
   // Attempt to open the file name.
   void* handle=dlopen(fullname.c_str(), RTLD_NOW);
   if(!handle){
@@ -504,6 +522,7 @@
   if(!scene){
     throw InputError( "make_scene returned null" );
   }
+#endif
 
   return scene;
 
@@ -516,25 +535,39 @@
 
   // Assume an absolute path by default
   string fullname = name;
-  
+
   vector<string> dirs = split_string(scenePath, ':');
   for(vector<string>::iterator dir = dirs.begin(); dir != dirs.end(); dir++){
 
     fullname = *dir + "/"+name;
-    
+
     // Check to see if the file exists in the directory.
     struct stat statbuf;
     if(stat(fullname.c_str(), &statbuf) != 0){
       break;
     }
   }
-  
+
+#if 1
+  typedef void (*MakerType)(ReadContext &, const vector<string>&);
+  Plugin<MakerType> make_stack(fullname.c_str());
+  if (!make_stack.loadSymbol("make_stack")) {
+    if(printErrors){
+      cerr << "Stack configuration file found, but make_stack() function not 
found\n";
+    }
+    return;
+  }
+  ReadContext context(manta_interface);
+  MakerType make_stack_function = make_stack.function;
+  // Call the function.
+  (*make_stack_function)(context, args);
+#else
   // Open the file.
   void* handle=dlopen(fullname.c_str(), RTLD_NOW);
   if(!handle){
     throw InputError( "Could not load stack" );
   }
-  
+
   // Access the make_stack symbol
   void* stack_fn=dlsym(handle, "make_stack");
   if(!stack_fn){
@@ -543,16 +576,17 @@
     }
     return;
   }
-  
+
   ///////////////////////////////////////////////////////////////////////////
-  // Invoke the function.  
+  // Invoke the function.
   typedef void (*MakerType)(ReadContext &, const vector<string>&);
   MakerType make_stack = (MakerType)(stack_fn);
   ReadContext context(manta_interface);
-  
+
   // Call the function.
   (*make_stack)(context, args);
-  
+#endif
+
 }
 
 UserInterface* Factory::createUserInterface(const string& spec)




  • [Manta] r1900 - in trunk: Core Core/Util Engine/Factory, boulos, 12/03/2007

Archive powered by MHonArc 2.6.16.

Top of page