由于某种原因,当使用 Boost Python 将以下内容公开给 python 时,唯一的指针构造函数(obj 构造函数)失败。这以前对我有用,不知道为什么它停止了。
#pragma once
#include <memory>
#include <boost/asio/ssl.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/beast.hpp>
//Socket
class Contextable
{
public:
Contextable() : m_ssl(boost::asio::ssl::context::sslv23_client) {}
protected:
boost::asio::io_context m_ctx;
boost::asio::ssl::context m_ssl;
};
class SocketExample : protected Contextable
{
using SocketImp = boost::beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>;
public:
SocketExample()
{
}
void constructSocket()
{
m_ws = std::make_unique<SocketImp>(m_ctx, m_ssl); //kills jupyter kernel
std::cout << "DONE. OPEN FLAG: " << m_ws->is_open() << std::endl;
}
private:
std::unique_ptr<SocketImp> m_ws;
};
//ExampleModule
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(ExampleModule)
{
boost::python::class_<SocketExample, std::shared_ptr<SocketExample>, boost::noncopyable>("SocketExample")
.def(boost::python::init<>())
.def("constructSocket", &SocketExample::constructSocket)
;
}
##Jupyter Notebook
import ExampleModule as m
socket = m.SocketExample()
socket.constructSocket() ##kills kernel
知道我做错了什么吗?当使用 C++ 运行时,如下所示不会失败。
SocketExample sk;
sk.constructSocket(); //works fine when run inside main.cpp
您很可能引入了 Jupyter 环境中缺少的间接依赖项。
我已经编译了你的源代码(稍作修改)
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/beast.hpp>
#include <iostream>
#include <memory>
// Socket
class Contextable {
public:
Contextable() : m_ssl(boost::asio::ssl::context::sslv23_client) {}
protected:
boost::asio::io_context m_ctx;
boost::asio::ssl::context m_ssl;
};
class SocketExample : protected Contextable {
using SocketImp = boost::beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>;
public:
SocketExample() { std::cout << "SocketExample constructor" << std::endl; }
~SocketExample() { std::cout << "SocketExample destructor" << std::endl; }
void constructSocket() {
m_ws = std::make_unique<SocketImp>(m_ctx, m_ssl);
std::cout << "DONE. OPEN FLAG: " << m_ws->is_open() << std::endl;
}
private:
std::unique_ptr<SocketImp> m_ws;
};
// ExampleModule
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(ExampleModule) {
boost::python::class_<SocketExample, std::shared_ptr<SocketExample>, boost::noncopyable>("SocketExample")
.def(boost::python::init<>())
.def("constructSocket", &SocketExample::constructSocket);
}
使用 python 进行简单的 CLI 测试:
启动 Jupyter 笔记本1:
作为为什么事情会崩溃的一个例子,让我通过添加来在 C++ 模块上启用 ASAN/UBSAN
-fsanitize=undefined,address
到编译器标志。现在,Python CLI 测试实际上将显示出了什么问题:
我们可以告诉 python 先加载 ASAN²:
LD_PRELOAD=/nix/store/jfilhsiqdgm4nks2z6labx3iq9qd077a-gcc-13.3.0-lib/lib/libasan.so.8 python ./test.py
然后它就起作用了,给出了一些预期的内存泄漏报告:
但是,如果您尝试将其加载到 Jupyter 笔记本中,它将不知道如何加载 ASAN 依赖项并失败:
希望这能让您了解可能出现的技术问题,以及如何开始诊断它们(至少在我使用的类似 Linux 的系统上)。
一般来说,尝试减少(非标准)编译器/链接器标志的数量。检查共享库(可加载模块)是否有任何意外/未知/不可用的依赖项。在 Windows 上,您可以使用 Dependency Walker 或更高级的 - Fusion Logging 进行检查。
¹ 免责声明 我从未使用过 Jupyter,所以我全新安装了它,然后就开始使用它了...
² 我使用
ldd ExampleModule.so
得到了这条路径