Passing shared_ptr to another python module

145 views Asked by At

I have made a python module by boost python.

It is a logging module, the log consumer looks like that. Basically there is an abstract interface and the file logger is derived from that.

class DIAGNOSTICS_API ISink : public boost::enable_shared_from_this<ISink>
{
public:
    virtual ~ISink();
    virtual void AddEntry(Entry& logEntry) = 0;
    virtual bool ShallLog(const std::string& domain, Severity severity) = 0;
};

class DIAGNOSTICS_API DomainRulesBasedSink : public ISink
{
    .........
}

class DIAGNOSTICS_API FileSink : public DomainRulesBasedSink
{
    .........
}

This code is packed into a python module.

boost::python::class_<Log::ISinkRealizer, boost::shared_ptr<Log::ISinkRealizer>, boost::noncopyable>("ISink", boost::python::no_init)
    .def("AddEntry", boost::python::pure_virtual(&Log::ISinkRealizer::AddEntry))
    .def("ShallLog", boost::python::pure_virtual(&Log::ISinkRealizer::ShallLog));

boost::python::class_<Log::FileSink, boost::shared_ptr<Log::FileSink>, boost::python::bases<Log::ISink>, boost::noncopyable>
    ("FileSink", boost::python::init<const std::string&>())
    .def("AddDomain", &Log::FileSink::AddDomain)
    .def("Create", &Log::FileSink::Create)
    .staticmethod("Create");

boost::python::class_<Log::Source, boost::shared_ptr<Log::Source>>("Source", boost::python::init<const std::string&>())
    .def(boost::python::init<const std::string&, boost::shared_ptr<Log::ISink>>())
    .def("SetSink", &Log::Source::SetSink);

When I use instantiate the FileSink in python then I can give it into a constructor of a class that is in the same module.

However when I try to plugin the same instance into another class that is in another module then it does not work.

Python argument types in
    SensorController.__init__(SensorController, FileSink)
did not match C++ signature:
    __init__(struct _object * __ptr64, class boost::shared_ptr<class Log::ISink>)

I am quite sure that python creates the FileSink by a shared_ptr, but somehow when I want to give it to a constructor in another module (SensorController class) then it sees "FileSink" instead of "boost::shared_ptr"

What magic shall be used that my shared_ptr object would be visible to other modules not only to the modules where this class was instantiated.

1

There are 1 answers

0
user2281723 On BEST ANSWER

The problem was as it was explained in link here. When Boost Python is used as a static library then the type conversion registry (how to convert between python objects and C++ objects) is duplicated as many times as the boost python is linked. However when it is linked as a dynamic library then it has only one type conversion registry and all python modules see each other types.