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.
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.