[C++-sig] problems with embedded python

Birgir Sigurjonsson birgir-s at online.no
Wed Jan 3 15:45:29 CET 2007


Hi, I am still trying to get embedded boost.python to work
correctly. Below is my code.

The problem is that when the following statment in main.cpp
is executed

a135->load("/tmp/xyz.xyz");

I get Abort after the following line is printed out
Python running: 6-->  <python_plugins.ascii135loader.Ascii135Loader object at 0x2a955bd260>

I think somehow that the a135 that is returned by the following line in main.cppboost::shared_ptr<AbstractLoader> a135 = AbstractLoaderFactory::create("Ascii135");

is not complete or corrupted.

It might be that my AbstractLoaderFactoryWrap is not 100% correct.


When I comment out the line a135->load("/tmp/xyz.xyz"); this is printed to the console

-->Importing plugins
import python_plugins.ascii135loader as ipack
Python running: 1--> Ascii135Loader
AbstractLoaderFactor ctor
registry = 0x543340
Python running: 4--> Ascii135LoaderFactory(AbstractLoaderFactory) __init__
<bound method Ascii135LoaderFactory.__init__ of <python_plugins.ascii135loader.Ascii135LoaderFactory object at 0x2a955bc890>>
True
-->Done Importing plugins
hello world
registry = 0x543340
registry = 0x543340
Ascii135
registry = 0x543340
registry = 0x543340
Creating AbstractLoader = Ascii135
Python running: 5--> Ascii135LoaderFactory::make
constructor AbstractLoader::AbstractLoader
Python running: 2--> Ascii135Loader(AbstractLoader) __init__
<bound method Ascii135Loader.__init__ of <python_plugins.ascii135loader.Ascii135Loader object at 0x2a955bc260>>
Python running: 6-->  <python_plugins.ascii135loader.Ascii135Loader object at 0x2a955bc260>
calling Py_Finalize()
Done
destructor AbstractLoader::~AbstractLoader
destructor AbstractLoader::~AbstractLoader

Any idea what I am doing wrong?

Best regards,
Birgir Sigurjonsson.


-------- framework/abstractloader.h ----------------
#ifndef FRAMEWORK_ABSTRACTLOADER_H
#define FRAMEWORK_ABSTRACTLOADER_H

#include <string>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>

class AbstractLoader : private boost::noncopyable {
public:
  AbstractLoader();
  bool load(const std::string& path);
  virtual ~AbstractLoader();
  virtual bool load_impl(const std::string& path) = 0;
};
#endif

-------- framework/abstractloader.cpp ----------------
#include <iostream>

AbstractLoader::AbstractLoader(){
  std::cout << "constructor AbstractLoader::AbstractLoader\n";
}

AbstractLoader::~AbstractLoader() {
  std::cout << "destructor AbstractLoader::~AbstractLoader\n";
}

bool AbstractLoader::load(const std::string& path) {
  return load_impl(path);
}

-------- framework/abstractloaderfactory.h ----------------
#ifndef FILE_IMPORT_FRAMEWORK_ABSTRACTLOADERFACTORY_H
#define FILE_IMPORT_FRAMEWORK_ABSTRACTLOADERFACTORY_H

#include <map>
#include <functional>
#include <boost/utility.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/shared_ptr.hpp>
#include <framework/abstractloader.h>

class NoSuchLoader : std::exception {
public:
  NoSuchLoader(const std::string path) throw ();
  virtual ~NoSuchLoader ()  throw ();

  virtual const char * what () const throw ();

private:

  std::string m_path;
};

template <typename Pair>
struct first_from_pair : public std::unary_function<Pair, typename Pair::first_type> {
    typename Pair::first_type operator() (const Pair& pair) const {
      return pair.first;
  }
};

class AbstractLoaderFactory : private boost::noncopyable {
private:
  typedef std::map<std::string, AbstractLoaderFactory*>  Registry;
  typedef first_from_pair<Registry::value_type> RegistryKeyFunction;

public:

  typedef boost::transform_iterator<RegistryKeyFunction, Registry::const_iterator> iterator;

  AbstractLoaderFactory(const std::string& key);
  virtual ~AbstractLoaderFactory();

  static boost::shared_ptr<AbstractLoader> create(const std::string &key);

  static iterator begin();
  static iterator end();

  virtual  AbstractLoader* make() = 0;

protected:
  void unregister(const std::string &key);

private:
  static Registry& registry();
};

#endif

-------- framework/abstractloaderfactory.h ----------------
#include <cassert>
#include <iostream>
#include <boost/tuple/tuple.hpp>
#include <framework/abstractloaderfactory.h>

NoSuchLoader::NoSuchLoader(const std::string path) throw ():
        m_path(path) {
}

NoSuchLoader::~NoSuchLoader ()  throw () {
}

const char * NoSuchLoader::what () const throw () {
  return m_path.c_str();
}

AbstractLoaderFactory::AbstractLoaderFactory(const std::string& key) {
  bool inserted;
  Registry::iterator pos;
  std::cerr << "AbstractLoaderFactor ctor\n";
  boost::tie(pos,inserted) = registry().insert(std::make_pair(key, this));
  assert(inserted);
}

AbstractLoaderFactory::~AbstractLoaderFactory() {
}

void AbstractLoaderFactory::unregister(const std::string& key) {
  size_t elements = registry().erase(key);
  assert(elements == 1);
}

boost::shared_ptr<AbstractLoader>
AbstractLoaderFactory::create (const std::string &key) {
  Registry::const_iterator p = registry().find(key);

  if (p == registry().end()) {
      throw NoSuchLoader(key);
  }
  std::cout << "Creating AbstractLoader = "<< key << "\n";
  AbstractLoaderFactory * alf = (*p).second;

  AbstractLoader* a = alf->make();

  boost::shared_ptr<AbstractLoader> concrete_loader(a);
  return concrete_loader;
}


AbstractLoaderFactory::Registry &
AbstractLoaderFactory::registry() {
  static Registry* registry = new Registry;
  std::cerr << "registry = " << registry << std::endl;
  return *registry;
}

AbstractLoaderFactory::iterator
AbstractLoaderFactory::begin() {
    return iterator(registry().begin());
}

AbstractLoaderFactory::iterator
AbstractLoaderFactory::end() {
    return iterator(registry().end());
}

----- plugins/python_plugins/asci135loader.py
def loadPackage(pack):
    success = False

    print '-->Importing plugins'
    import_pack_as_ipack = 'import python_plugins.' + pack + ' as ipack'
    print import_pack_as_ipack
    try:
        exec import_pack_as_ipack
        success = True
    except ImportError, e:
        print e
        success = False
    return success


success =  loadPackage('ascii135loader')

print success
print '-->Done Importing plugins'


----- plugins/python_plugins/asci135loader.py
from import_framework import AbstractLoader, AbstractLoaderFactory

print 'Python running: 1--> Ascii135Loader'

class Ascii135Loader(AbstractLoader):
    def __init__(self):
        super(Ascii135Loader, self).__init__()
        print  'Python running: 2--> Ascii135Loader(AbstractLoader) __init__'
        print self.__init__
    def load_impl(self):
        print self.load_impl
        print  'Python running: 3--> Ascii135Loader(AbstractLoader) load_impl HARD WORK'
        return True

class Ascii135LoaderFactory(AbstractLoaderFactory):
    def __init__(self, key):
        super(Ascii135LoaderFactory, self).__init__(key)
        print  'Python running: 4--> Ascii135LoaderFactory(AbstractLoaderFactory) __init__'
        print self.__init__

    def make(self):
        print  'Python running: 5--> Ascii135LoaderFactory::make'
        something = Ascii135Loader()
        print  'Python running: 6--> ',something
        return something

register_this = Ascii135LoaderFactory("Ascii135")

------------ main.cpp --------
#include <cstdio>
#include <iostream>
#include <framework/abstractloaderfactory.h>
#include <framework/abstractloader.h>

#include <boost/shared_ptr.hpp>

int main(int argc, char *argv[]) {
  Py_Initialize();

  boost::python::object main_module((
    boost::python::handle<>(boost::python::borrowed(PyImport_AddModule("__main__")))));
  boost::python::object main_namespace = main_module.attr("__dict__");

  boost::python::handle<> ignored ((
    PyRun_String( "import sys\n"
                 "sys.path.append('/disk/armamix/p4workspaces/birgirs/sandbox/file_import/plugins')\n"
                 "sys.path.append('/disk/armamix/p4workspaces/birgirs/install/sandbox/file_import/linux-amd64-gcc_3_2-debug/lib')\n"
                 "import pluginloader\n"
                 "print 'hello world'" ,
                 Py_file_input,
                 main_namespace.ptr(),
                 main_namespace.ptr())
  ));

  AbstractLoaderFactory::iterator p = AbstractLoaderFactory::begin();
  AbstractLoaderFactory::iterator p_end = AbstractLoaderFactory::end();
  while(p != p_end) {
    std::cout << *p << "\n";
    ++p;
  }

  boost::shared_ptr<AbstractLoader> a135 = AbstractLoaderFactory::create("Ascii135");
//  a135->load("/tmp/xyz.xyz");

  std::cout << "calling Py_Finalize()\n";
  Py_Finalize();
  std::cout << "Done\n";
  return 0;
}


More information about the Cplusplus-sig mailing list