Python boost to-Python converter for class already registered second conversion method ignored

Python boost to-Python converter for class already registered second conversion method ignored

我有下一个class(已简化):

class Value
{
    public:

    Value();
    ~Value();

    void setValue(int value);
    void setValue(double value);
}

我有 python 升压模块:

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>

BOOST_PYTHON_MODULE(py_classes) 
{
    typedef std::vector<Value> VectorClass;

    boost::python::type_info infoVectorValue = boost::python::type_id<VectorClass>();

    const boost::python::converter::registration* regVectorValue = boost::python::converter::registry::query(infoVectorValue);

    if (regVectorValue == NULL || (*regVectorValue).m_to_python == NULL) {
        class_<VectorClass>("std_vector_value")
            .def(vector_indexing_suite<VectorClass>());
    }
}

Python 脚本从 dll 库调用并使用来自 pyd py_classes 的容器。第一次调用 dll-library 时 std_vector_value type 没有任何问题。 当我在可执行文件中重新加载 dll 库时,我收到下一个警告:

RuntimeWarning: to-Python converter for class
boost::python::detail::container_element<class std::vector<class Value,class std::allocator<class Value> >,
unsigned __int64,class boost::python::detail::final_vector_derived_policies
<class std::vector<class Value,
class std::allocator<class Value> >,0> > 
already registered; second conversion method ignored.
return f(*args, **kwds)

所以,这意味着:

并且这种情况只出现在容器classes中(如果我使用std::vectorstd::map——一般如果我使用vector_indexing_suitemap_indexing_suite) ,对于 class 值,此警告不会出现。

我做错了什么?

接下来是问题:boost python 是从一个 exe 进程加载的,但是由不同的 DLL 库加载的。这意味着我有 3 个执行 python 脚本的 DLL 库。 Python 在重新加载 DLL 库(在进程内部调用 FreeLibrary 和 LoadLibrary 而无需重新启动进程)之前,提升类型没有任何问题。 Python boost 具有静态变量 register(寄存器是此变量的名称)存储对 python boost 类型的引用。 启动可执行文件时,对类型的引用将添加到静态变量 register。 因此,此检查正常工作:

boost::python::type_info infoVectorValue = boost::python::type_id<VectorClass>();
const boost::python::converter::registration* regVectorValue = boost::python::converter::registry::query(infoVectorValue);
if (regVectorValue == NULL || (*regVectorValue).m_to_python == NULL) {

但是当 DLL 库被卸载时,对这些 python 提升类型的引用被留在静态变量 register 中,它们导致被释放的 DLL 库地址。这意味着当再次加载库时,类型检查获取所需类型的引用(VectorClass 在我的例子中)没有问题,但这个引用已经坏了。

所以,这个问题的解决方案是 link 将 python 库静态地提升到每个 DLL 库 - 每个 DLL 库都有它自己的静态变量 register 和提升 python 类型 为每个 DLL 库创建引用,当卸载 DLL 库时,register 变量为此 DLL 被销毁。