问题标签 [signals2]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 当回调与 boost::signals2::signal 断开连接时执行代码
connect
简短:当使用断开连接的回调连接时,有什么方法可以执行代码?
Long:我有一个包含多个回调的类,这些回调很昂贵,我只想为用户感兴趣的那些生成回调:
现在我想在stop_callback
绑定到信号的所有回调断开连接时执行。
signals2 - 信号2:带有模板化参数的信号
我正在为相机类设计一个基类。目的是使用信号通知客户端新的可用图像。相机可能有 8 位或 16 位像素。我正在尝试将它们模板化如下:
在 MSVS 2008 中,当我从 派生一个类时ICamera<uint8_t>
,在 typedef 上存在编译错误slot_type
,首先是:“缺少;在标识符 CaptureSlot 之前”。也就是说,此时CaptureSig::slot_type
没有定义。
除了在每个派生类中定义信号和槽之外,有没有办法超越这一点?
更新:实际上不是导致问题的信号参数,而是模板中存在信号定义。如果将信号的签名更改为固定类型,则会出现相同的错误。
c++ - Boost::signals2 传递无效数据
我已经做了大约 20 年的 C/C++ 开发人员,但模板一直是我的弱点。随着模板编程在 C++11 和 C++14 标准中变得越来越有用和复杂,我决定尝试一个练习来学习。我已经取得了一定的成功,但我遇到了一个问题。我有以下课程:
此代码可能会进入一个大型框架,该框架会加载多个模块,这些模块是 linux 上的动态库。这个想法是让给定的模块能够调用:
回调可能是带有签名 void(ParamTypes) 的函数,或者是 std::bind() 对带有签名 void(ParamTypes) 的函数的结果。
然后另一个模块将能够调用:
并且每个调用了consume_event 的模块都会使用ParamValues 调用它的处理程序。
这似乎在几乎所有情况下都有效,除非我将引用传递给自定义类,如下所示:
在这种情况下,连接到信号的函数接收到 0xa,并在尝试将其视为 ip_stats_t & 时立即崩溃。
输出是:
更新:我只是注意到它在通过引用传递任何变量时会做同样的事情,而不仅仅是上面的自定义类。
此外,请注意,此问题中没有SSCCE,因为任何 SSCCE 不变式都有效。在将工作代码放入上述框架之前,不会出现问题。
Update2:这里真正的问题是,如何才能使这种设计变得更好。这不仅不能正常工作,而且在语法上,它很臭。它丑陋、不优雅,而且真的没有什么好处,除了它做了我想要它做的事情并增加了我对模板的理解。
Update3:我现在 100% 确认这与我传递的数据类型无关。如果我通过引用传递任何变量,则插槽始终接收 0xa 作为引用的地址。这包括 std::strings,甚至 int。如果我按值传递任何变量,则该值的复制构造函数最终会接收 0xa 作为要从中复制的值的引用。这只发生在从模块 A 中创建的信号调用模块 B 中的插槽时。我错过了什么?
有任何想法吗?谢谢!
c++ - 使用 boost::signals2 和卸载 DLL 时访问冲突
我试图弄清楚这个问题。
假设您有一个boost::signals2
用于在对象之间进行通信的代码。让我们称它们为“色标”。这些色阶的代码通常与使用它们的代码位于同一个 DLL 中。让我们称之为main.dll
但有时来自其他 DLL 的代码需要使用这些对象,这就是问题的根源。
基本上,应用程序非常大,大多数 DLL 被加载以完成一些工作,然后它们被卸载。对于包含色阶代码的 DLL,情况并非如此,它在应用程序正常运行时必须卸载。
因此,当其中一个 DLL 被加载(让我们调用它tools.dll
)并且一些代码运行时,它可能想要使用这些色阶对象并与它们通信,所以我连接到这些对象提供的信号。
问题是它boost
非常懒惰而且很聪明,当你disconnect()
插入插槽时,它实际上并没有擦除connection
与它相关的东西(比如boost::bind
对象等)。它只是设置了一个标志,表明它connection
现在已断开连接并稍后将其清理(实际上,当您连接新插槽时它会清理其中的 2 个对象,而当您调用 1.57 版的信号时会清理其中的 1 个)。您可能已经看到了它的发展方向。
因此,当您不需要更多工具时,您可以断开这些信号,然后卸载应用程序tools.dll
。
然后在稍后阶段,一些代码从main.dll
导致调用的色阶信号之一执行。boost::signals2
去调用它,但在它试图清理一个断开连接的插槽之前。这是发生访问冲突的地方,因为内部连接有一个 shared_state 对象或类似的东西,它试图以线程安全的方式清理自己。但它面临的问题是,它试图调用的代码已经不存在,因为 DLL 被卸载,所以抛出了 Access Violation 异常。
我试图通过在卸载 DLL 之前使用一些虚拟参数调用信号以及连接然后断开更多插槽来解决这个问题(这是一个愚蠢的想法,因为它不能解决问题,但只是将它相乘)一些预定义的次数(比所有插槽多 2 或 3 倍)。
它起作用了,或者我是这么认为的,因为现在它不会立即崩溃,而是在下次加载相同的tools.dll
. 我仍然需要弄清楚它在哪里以及为什么会崩溃,但它在里面的其他地方boost
。
所以,我想问一下,我有哪些修复它的选择?我的想法是
- 以更简单的方式实现我自己的连接
- 提供一种更简单的通信方式,例如回调
boost
为如此懒惰和聪明找到解决方法。
c++ - 增强信号2 - 通过插槽断开连接时出错
我想通过一个插槽来断开连接,就像在boost signals2 文档中一样:
Pass slot to disconnect:在这个接口模型中,通过 sig.disconnect(slot_func) 执行与 sig.connect(typeof(sig)::slot_type(slot_func)) 连接的 slot 的断开连接。
...但是在调用断开连接时出现错误(请参阅http://cpp.sh/45q6):
错误:'operator==' 的重载不明确
(操作数类型是 'boost::signals2::slot >::slot_function_type {aka boost::function}'
和 'const boost::function')
我错了什么?
c++ - 升压信号参考对象超出范围?
现在由先前的 boost::bind 返回的临时对象超出范围并被销毁但是临时对象通过引用传递给 AAA::Connect。现在让我们说在某个时候,对象 a.FireSignal() 被调用,信号是否调用了一个已经被销毁的函数对象???不然怎么操作???
c++ - Boost::signals2 和 const-ness
有一些可观察的类,我天真地使用信号2的方式是提供一个成员信号,以便任何人都可以连接
为了更好的封装,可能会添加一些 publicsubscribe
和 hideaSignal
以避免外部类调用信号。
现在,问题是该boost::signals2::signal::connect
方法是non-const
可以理解的,因为连接列表已被修改。但是,这会阻止将信号用于仅观察类,这些类只想对修改做出反应Observable
而不修改它。
解决这个问题的一种方法是让mutable
那些发送const this
和const subscribe
运行的信号。
那是反模式吗?
另一种解决方法可能是使用允许连接到 const 和非 const Observable 的中间代理类,但是这样我就会失去已经为我准备好的信号的任何优势。
或者我只需要放弃 const 正确性?
或者有什么我想念的?
c++ - boost::signals2: 连接到不同类的插槽
我正在尝试在我的程序中使用 boost::signals2 功能。在我的名为“Solid”的“主类”中,我有一个在构造函数体内初始化的成员(所以在成员初始化器列表之后),如下所示:
如果信号是由某个函数触发的,我不想调用“OtherClass”的成员(pointer_M 指向的),而是“Solid”的成员,即刚刚初始化 pointer_M 的类。
我尝试了以下方法:
“call_this_function”是 Solid 的成员函数。不幸的是,有一堆错误消息。“OtherClass”和“Solid”没有继承关系。
我希望能得到一些建议来解决我的问题,因为我对 boost 非常缺乏经验。
最好的
c++ - 从回调 boost::signals c++ 中删除调用信号
我有以下代码在信号的回调之一期间删除信号:
我只是在这种“工作”中很幸运(因为它是未定义的行为)还是在信号2中有一些魔术指针计数阻止我把脚吹走?