You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Boost.Python向Python暴露C++变量并在循环中实时更新?

Boost.Python实时暴露C++变量给Python的解决方案

咱们先来拆解下你遇到的问题:你拿到<property object>是因为你访问的是类的属性,而不是类的实例cbtest.callback_handler是Python中的类对象,gui_cancel是Boost.Python为这个类创建的属性描述符,只有当你拿到这个类的实际实例时,访问gui_cancel才能获取到C++端的真实变量值。

下面给你两种可行的实现方案,分别适配轮询获取和主动通知的场景:

方案1:通过实例访问实现实时轮询

这个方案适合Python端需要主动周期性检查C变量的场景,核心是确保Python拿到的是Ccallback_handler的实际实例,而不是类本身。

步骤1:修改C++代码暴露实例

首先在C++中提供一个获取全局/单例callback_handler实例的函数,并通过Boost.Python暴露:

#include <boost/python.hpp>
using namespace boost::python;

class callback_handler : boost::noncopyable {
public:
    bool gui_cancel = false;
    // 这里可以添加你GUI更新var4/gui_cancel的逻辑
};

// 提供全局实例的访问入口(单例模式)
callback_handler& get_callback_instance() {
    static callback_handler instance;
    return instance;
}

BOOST_PYTHON_MODULE(cbtest) {
    class_<callback_handler, boost::noncopyable>("callback_handler", no_init)
        .def_readwrite("gui_cancel", &callback_handler::gui_cancel);
    
    // 暴露获取实例的函数,注意返回引用避免拷贝
    def("get_callback_instance", &get_callback_instance, 
        return_value_policy<reference_existing_object>());
}

步骤2:Python端访问实例获取实时值

现在Python代码中要先获取实例,再访问变量,这样每次访问都会直接读取C++端的最新值:

import cbtest
import time

# 获取C++端的callback_handler实例,而不是类
handler = cbtest.get_callback_instance()

# 测试初始值
print(f"初始gui_cancel值: {handler.gui_cancel}")

# 循环实时检查更新(模拟你的业务逻辑)
while True:
    current_val = handler.gui_cancel
    if current_val:
        print("检测到GUI取消信号,退出循环")
        break
    print(f"当前gui_cancel值: {current_val}")
    time.sleep(0.1)  # 加延迟避免CPU占用过高

方案2:通过回调函数实现主动通知

如果需要C++端变量更新时主动通知Python(而不是Python轮询),可以给callback_handler添加回调函数成员,让Python注册回调逻辑。

步骤1:修改C++代码支持回调

#include <boost/python.hpp>
#include <functional>
using namespace boost::python;

class callback_handler : boost::noncopyable {
public:
    bool gui_cancel = false;
    // 定义回调函数类型
    std::function<void(bool)> on_cancel_updated;

    // 假设GUI更新时会调用这个方法来更新变量并触发回调
    void update_gui_cancel(bool new_val) {
        gui_cancel = new_val;
        // 如果Python注册了回调,就触发它
        if (on_cancel_updated) {
            on_cancel_updated(new_val);
        }
    }
};

callback_handler& get_callback_instance() {
    static callback_handler instance;
    return instance;
}

BOOST_PYTHON_MODULE(cbtest) {
    class_<callback_handler, boost::noncopyable>("callback_handler", no_init)
        .def_readwrite("gui_cancel", &callback_handler::gui_cancel)
        .def_readwrite("on_cancel_updated", &callback_handler::on_cancel_updated);
    
    def("get_callback_instance", &get_callback_instance, 
        return_value_policy<reference_existing_object>());
}

步骤2:Python端注册回调

import cbtest

# 定义回调逻辑,C++端更新时会自动调用
def handle_cancel_update(new_val):
    print(f"GUI取消状态已更新: {new_val}")
    if new_val:
        print("执行取消相关的业务逻辑...")

# 获取实例并注册回调
handler = cbtest.get_callback_instance()
handler.on_cancel_updated = handle_cancel_update

# 保持Python进程运行(根据你的实际业务场景调整)
import time
while True:
    time.sleep(1)

关键误区说明

你之前的代码holder = cbtest.callback_handler; print(holder.gui_cancel)中,holder是Python的类对象,不是C类的实例,所以gui_cancel是Boost.Python生成的属性描述符(即<property object>),只有访问实例的gui_cancel才能拿到C端的实际变量值,而且因为是直接引用内存,C++端更新后Python端能实时读取到最新值。

内容的提问来源于stack exchange,提问作者Karls

火山引擎 最新活动