PyBind11 destructor not invoked?(是否未调用PyBind11析构函数?)
问题描述
我有一个用PyBind11
包装的c++
类。问题是:当Python
脚本结束时,c++
destructor
不会被自动调用。这会导致不整洁的退出,因为网络资源需要由析构函数释放。
作为一种解决办法,有必要显式删除Python
对象,但我不明白为什么!
请解释一下这里出了什么问题,以及当Python
对象被垃圾回收时如何自动调用destructor
?
Pybind11绑定代码:
py::class_<pcs::Listener>(m, "listener")
.def(py::init<const py::object &, const std::string &, const std::string &, const std::string &, const std::string &, const std::set<std::string> &, const std::string & , const bool & , const bool & >(), R"pbdoc(
Monitors network traffic.
When a desired data source is detected a client instance is connected to consume the data stream.
Reconstructs data on receipt, like a jigsaw. Makes requests to fill any gaps. Verifies the data as sequential.
Data is output by callback to Python. Using the method specified in the constructor, which must accept a string argument.
)pbdoc");
在Python中:
#Function to callback
def print_string(str):
print("Python; " + str)
lstnr = listener(print_string, 'tcp://127.0.0.1:9001', clientCertPath, serverCertPath, proxyCertPath, desiredSources, 'time_series_data', enableCurve, enableVerbose)
#Run for a minute
cnt = 0
while cnt < 60:
cnt += 1
time.sleep(1)
#Need to call the destructor explicity for some reason
del lstnr
推荐答案
正如评论中提到的,这种行为的直接原因是Python型垃圾回收器:当对象的引用计数器变为零时,垃圾回收器可能销毁该对象(从而调用C++析构函数),但它不一定要在那个时刻这样做。
这个想法在这里的回答中得到了更充分的阐述:
https://stackoverflow.com/a/38238013/790979
正如上面的链接中所提到的,如果您要在对象的生命周期结束时在Python中进行清理,那么context management是一个很好的解决方案,您可以在对象的包装器中定义__enter__
和__exit__
(无论是在pybind11中还是在Python本身中),让__exit__
释放网络资源,然后在Python客户端代码中,类似于:
with listener(print_string, 'tcp://127.0.0.1:9001', clientCertPath, serverCertPath, proxyCertPath, desiredSources, 'time_series_data', enableCurve, enableVerbose) as lstnr:
# Run for a minute
cnt = 0
while cnt < 60:
cnt += 1
time.sleep(1)
这篇关于是否未调用PyBind11析构函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:是否未调用PyBind11析构函数?
基础教程推荐
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 设计字符串本地化的最佳方法 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- C++,'if' 表达式中的变量声明 2021-01-01