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)
所以,这意味着:
- 第一次加载dll库时,to-python转换器正常注册,python脚本可以使用
std_vector_value
类型。
- 重新加载 dll 库时(
FreeLibrary
和 LoadLibrary
函数),to-python 转换器尝试再次注册并检查它是否已注册说它已经已经注册,但我无法使用 python. 中的 std_vector_value
类型
并且这种情况只出现在容器classes中(如果我使用std::vector
或std::map
——一般如果我使用vector_indexing_suite
或map_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 被销毁。
我有下一个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)
所以,这意味着:
- 第一次加载dll库时,to-python转换器正常注册,python脚本可以使用
std_vector_value
类型。 - 重新加载 dll 库时(
FreeLibrary
和LoadLibrary
函数),to-python 转换器尝试再次注册并检查它是否已注册说它已经已经注册,但我无法使用 python. 中的
std_vector_value
类型
并且这种情况只出现在容器classes中(如果我使用std::vector
或std::map
——一般如果我使用vector_indexing_suite
或map_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 被销毁。