将 shared_ptr 传递给另一个 python 模块
Passing shared_ptr to another python module
我通过 boost python 制作了一个 python 模块。
它是一个日志记录模块,日志消费者看起来像这样。基本上有一个抽象接口,文件记录器是从中派生的。
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
{
.........
}
此代码打包到 python 模块中。
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);
当我在 python 中使用实例化 FileSink 时,我可以将它提供给同一模块中的 class 的构造函数。
然而,当我尝试将同一个实例插入另一个模块中的另一个 class 时,它不起作用。
Python argument types in
SensorController.__init__(SensorController, FileSink)
did not match C++ signature:
__init__(struct _object * __ptr64, class boost::shared_ptr<class Log::ISink>)
我很确定 python 通过 shared_ptr 创建了 FileSink,但是不知何故,当我想将它提供给另一个模块(SensorController class)中的构造函数时,它看到 "FileSink" 而不是 "boost::shared_ptr"
我的 shared_ptr 对象将对其他模块可见,而不仅仅是对实例化此 class 的模块可见,应该使用什么魔法。
问题如 link 中所述。当 Boost Python 用作静态库时,类型转换注册表(如何在 python 对象和 C++ 对象之间进行转换)被复制的次数与 boost python 链接的次数一样多。但是,当它作为动态库链接时,它只有一个类型转换注册表,所有 python 模块都可以看到其他类型。
我通过 boost python 制作了一个 python 模块。
它是一个日志记录模块,日志消费者看起来像这样。基本上有一个抽象接口,文件记录器是从中派生的。
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
{
.........
}
此代码打包到 python 模块中。
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);
当我在 python 中使用实例化 FileSink 时,我可以将它提供给同一模块中的 class 的构造函数。
然而,当我尝试将同一个实例插入另一个模块中的另一个 class 时,它不起作用。
Python argument types in
SensorController.__init__(SensorController, FileSink)
did not match C++ signature:
__init__(struct _object * __ptr64, class boost::shared_ptr<class Log::ISink>)
我很确定 python 通过 shared_ptr 创建了 FileSink,但是不知何故,当我想将它提供给另一个模块(SensorController class)中的构造函数时,它看到 "FileSink" 而不是 "boost::shared_ptr"
我的 shared_ptr 对象将对其他模块可见,而不仅仅是对实例化此 class 的模块可见,应该使用什么魔法。
问题如 link 中所述。当 Boost Python 用作静态库时,类型转换注册表(如何在 python 对象和 C++ 对象之间进行转换)被复制的次数与 boost python 链接的次数一样多。但是,当它作为动态库链接时,它只有一个类型转换注册表,所有 python 模块都可以看到其他类型。