[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