gpt4 book ai didi

已注册的类的 Python boost to-Python 转换器忽略了第二种转换方法

转载 作者:行者123 更新时间:2023-12-02 10:39:15 24 4
gpt4 key购买 nike

我有下一节课(它被简化了):

class Value
{
public:

Value();
~Value();

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

我有python boost模块:
#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>());
}
}

从 dll 库调用 Python 脚本并使用来自 pyd py_classes 的容器.首次调用 dll 库时 std_vector_value使用类型没有任何问题。
当我在可执行文件中重新加载 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)

所以,这意味着:
  • 第一次加载dll-library时,to-python转换器注册正常,python脚本可以使用std_vector_value类型。
  • 当重新加载 dll 库(FreeLibraryLoadLibrary 函数)时,to-python 转换器尝试再注册一次并检查它是否已注册说它已经注册,但我不能使用 std_vector_value从 python 输入。

  • 而且这种情况只出现在容器类中(如果我使用 std::vectorstd::map - 通常如果我使用 vector_indexing_suitemap_indexing_suite ),对于类 Value 这个警告不会出现。

    我究竟做错了什么?

    最佳答案

    接下来是问题:boost python 是从一个 exe 进程加载的,但由不同的 DLL 库加载。这意味着我有 3 个执行 python 脚本的 DLL 库。
    Python boost 类型在重新加载 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 boost 类型的引用会留在静态变量 register 中。它们会导致 DLL 库地址被释放。这意味着当再次加载库时,类型检查会毫无问题地获得所需类型的引用(在我的示例中为 VectorClass),但该引用已经损坏。

    因此,这个问题的解决方案是将 boost python 库静态链接到每个 DLL 库 - 每个 DLL 库都有自己的静态变量 register并 boost python 类型
    为每个 DLL 库创建引用,当卸载 DLL 库时, register此 DLL 的变量被销毁。

    关于已注册的类的 Python boost to-Python 转换器忽略了第二种转换方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52690339/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com