提振.Python中的Python c++对象引用:意外行为
Boost.Python C++ object reference in Python: unexpected behaviour
我有一个问题与Boost。Python的一个非常简单的用例。
我正在返回一个对象的引用,似乎我的python对象在某个阶段由于某种原因失去了它的c++对象的引用。
请参阅下面我的例子再现这个问题。
c++代码:#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
class Car {
public:
Car(std::string name) : m_name(name) {}
bool operator==(const Car &other) const {
return m_name == other.m_name;
}
std::string GetName() { return m_name; }
private:
std::string m_name;
};
class Factory {
public:
Factory(std::string name) : m_name(name) {}
bool operator==(const Factory &other) const {
return m_name == other.m_name
&& m_car_list == other.m_car_list;
}
Car& create_car(std::string name)
{
m_car_list.emplace_back(Car(name));
return m_car_list.back();
}
std::string GetName() { return m_name; }
std::vector<Car>& GetCarList() { return m_car_list;}
private:
std::string m_name;
std::vector<Car> m_car_list;
};
class Manufacturer {
public:
Manufacturer(std::string name) : m_name(name) {}
bool operator==(const Manufacturer &other) const {
return m_name == other.m_name
&& m_factory_list == other.m_factory_list;
}
Factory& create_factory(std::string name)
{
m_factory_list.emplace_back(Factory(name));
return m_factory_list.back();
}
std::string GetName() { return m_name; }
std::vector<Factory>& GetFactoryList() { return m_factory_list;}
private:
std::string m_name;
std::vector<Factory> m_factory_list;
};
BOOST_PYTHON_MODULE(carManufacturer)
{
using namespace boost::python;
class_<Manufacturer>("Manufacturer", init<std::string>())
.add_property("factory_list", make_function(&Manufacturer::GetFactoryList, return_internal_reference<1>()))
.add_property("name", &Manufacturer::GetName)
.def("create_factory", &Manufacturer::create_factory, return_internal_reference<>());
class_<Factory>("Factory", init<std::string>())
.add_property("car_list", make_function(&Factory::GetCarList, return_internal_reference<1>()))
.add_property("name", &Factory::GetName)
.def("create_car", &Factory::create_car, return_internal_reference<>());
class_<Car>("Car", init<std::string>())
.add_property("name", &Car::GetName);
class_<std::vector<Factory> >("FactoryList")
.def(vector_indexing_suite<std::vector<Factory> >());
class_<std::vector<Car> >("Car")
.def(vector_indexing_suite<std::vector<Car> >());
}
Python代码:import sys
sys.path[:0] = [r"binRelease"]
from carManufacturer import *
vw = Manufacturer("VW")
vw_bra_factory = vw.create_factory("Brazil Factory")
beetle = vw_bra_factory.create_car("Beetle69")
if vw_bra_factory is vw.factory_list[0]:
print("equal.")
else:
print("NOT EQUAL")
print("## I expected them to be the same reference..?")
print("vw_bra_factory Car List size : " + str(len(vw_bra_factory.car_list)))
print("Actual Car List size : " + str(len(vw.factory_list[0].car_list)))
print("## This still works. Maybe the python objects differ, but refer to the same C++ object. I can live with that.")
vw_sa_factory = vw.create_factory("South Africa Factory")
print("vw_bra_factory Car List size : " + str(len(vw_bra_factory.car_list)))
print("Actual Car List size : " + str(len(vw.factory_list[0].car_list)))
print("## .. what? why? brazil py object has no cars now? I don't get it. I can't have any of that.")
print("## What will happen if I create another car in the brazil factory?")
combi = vw_bra_factory.create_car("Hippie van")
print("vw_bra_factory Car List size : " + str(len(vw_bra_factory.car_list)))
print("Actual Car List size : " + str(len(vw.factory_list[0].car_list)))
print("## And another.")
citi_golf = vw_bra_factory.create_car("Citi golf")
print("vw_bra_factory Car List size : " + str(len(vw_bra_factory.car_list)))
print("Actual Car List size : " + str(len(vw.factory_list[0].car_list)))
print("## 'vw_bra_factory' must have lost its C++ reference it had to 'vw.factory_list[0]' when I created a new factory. Why?")
Python输出:NOT EQUAL
## I expected them to be the same reference..?
vw_bra_factory Car List size : 1
Actual Car List size : 1
## This still works. Maybe the python objects differ, but refer to the same C++ object. I can live with that.
vw_bra_factory Car List size : 0
Actual Car List size : 1
## .. what? why? brazil py object has no cars now? I don't get it. I can't have any of that.
## What will happen if I create another car in the brazil factory?
vw_bra_factory Car List size : 1
Actual Car List size : 1
## And another.
vw_bra_factory Car List size : 2
Actual Car List size : 1
## 'vw_bra_factory' must have lost its C++ reference it had to 'vw.factory_list[0]' when I created a new factory. Why?
这只是一个例子,以一个像样的方式再现我的实际工作的问题。在我的实际工作中,蟒蛇崩溃了在我创建第二个"工厂"并尝试将"汽车"添加到第一个"工厂"之后。c++的"create_car"方法在试图访问"factory"的"car"列表时发生崩溃
有谁知道问题是什么吗?
感谢邮件列表中有人解决了这个问题:
当我将向量大小保留为例如32时,它可以工作。
如果我在堆上分配存储在向量中的对象,
相关文章:
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- Pybind11:将元组列表从Python传递到C++
- 如何在c++中使用引用实现类似python的行为
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 递归列出所有目录中的C++与Python与Ruby的性能
- IPC使用多个管道和分支进程来运行Python程序
- 从python中调用C++函数并获取返回值
- 在C++中对T*类型执行std::move的意外行为
- Python 3.7 和 excess_args 的 SWIG 问题
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- Python中的for循环与C++有何不同
- 处理除以零会导致<csignal>意外行为
- 使用Pybind11向Python公开Eigen::张量
- vscode下的Arduino代码出现意外编译错误
- 使用++运算符会导致意外的结果
- 套接字读取后,我在缓冲区中看到意外输入
- Python str to C++ to Python str
- 如何使用Python从C++中读取谷物序列化数据
- 如何在C++中使用pybind11加载一个pickle python列表
- 提振.Python中的Python c++对象引用:意外行为