g_signal_connect 代理处理程序导致回调 GVariant * 数据未初始化
g_signal_connect on proxy handler results in callback GVariant * data uninitialized
为了在 dbus 上设置 Connman 信号回调,我几乎遵循 https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/GDBusProxy.html 上的示例,但是在我的回调函数中:
g_signal_connect(
this->manager_proxy,
"property-changed",
G_CALLBACK(on_manager_properties_changed),
this); //Pass in pointer to self so static function can operate on object.
g_signal_connect(
this->manager_proxy,
"technology-added",
G_CALLBACK(on_manager_tech_added),
this); //Pass in pointer to self so static function can operate on object.
g_signal_connect(
this->manager_proxy,
"technology-removed",
G_CALLBACK(on_manager_tech_removed),
this); //Pass in pointer to self so static function can operate on object
void
CM_InterfaceController::on_manager_properties_changed (
GDBusProxy *proxy,
GVariant *changed_properties,
const gchar* const *invalidated_properties,
gpointer user_data)
{
if(!user_data){CM_ERR("NO THIS * on_manager_properties_changed");return;}
CM_InterfaceController * ths = static_cast<CM_InterfaceController *>(user_data);
std::cout<<"on_manager_properties_changed"<<std::endl;
if(changed_properties){
std::cout<<"children: "<<g_variant_n_children(changed_properties)<<std::endl;
}
}
我被告知 GVariant * object 包含的 children 的数量是完全错误的。比如我的反馈:
Calling Extraction
Service List Size: 1
Identified Ethernet Link:
Path: /net/connman/service/ethernet_0800277d326e_cable
Type: ethernet
Sate: ready
Favorite: 0
Auto Connect: 0
Name: Wired
Net Mode: manual
Iface: eth0
Mac: 08:00:27:7D:32:6E
IP Address: 10.0.2.15
Net Mask: 255.255.255.0
on_manager_properties_changed
children: 139764141513856
on_manager_properties_changed
children: 145
on_manager_properties_changed
children: 139764141513856
on_manager_properties_changed
children: 145
这两个值都超出了范围,一个比另一个更明显。更重要的是,如果我尝试从 GVariant object 中解析值,即使只是尝试调用 g_variant_get_type_string,我也会出现段错误。 为什么我的回调 return 使用垃圾数据指针? 似乎如果它什么都没有,它至少应该 return 一个空指针。
编辑:Source Code https://drive.google.com/file/d/1E0Kg9JKW54gghUHbVyBJ0ysBIdqBlpVA/view?usp=sharing
还有一些dbus-monitor--系统输出:
signal time=1549641357.679460 sender=:1.3 -> destination=(null destination) serial=488 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "State"
variant string "ready"
signal time=1549641357.680844 sender=:1.3 -> destination=(null destination) serial=489 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "Nameservers"
variant array [
string "10.0.2.3"
]
signal time=1549641357.681186 sender=:1.3 -> destination=(null destination) serial=490 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "Domains"
variant array [
]
signal time=1549641357.681601 sender=:1.3 -> destination=(null destination) serial=491 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "Proxy"
variant array [
dict entry(
string "Method"
variant string "direct"
)
]
signal time=1549641357.681780 sender=:1.3 -> destination=(null destination) serial=492 path=/net/connman/technology/ethernet; interface=net.connman.Technology; member=PropertyChanged
string "Connected"
variant boolean true
signal time=1549641357.682210 sender=:1.3 -> destination=(null destination) serial=493 path=/; interface=net.connman.Manager; member=PropertyChanged
string "State"
variant string "ready"
signal time=1549641357.696004 sender=:1.3 -> destination=(null destination) serial=494 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "IPv4"
variant array [
dict entry(
string "Method"
variant string "dhcp"
)
]
signal time=1549641357.696227 sender=:1.3 -> destination=(null destination) serial=495 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "IPv4"
variant array [
dict entry(
string "Method"
variant string "dhcp"
)
dict entry(
string "Address"
variant string "10.0.2.15"
)
dict entry(
string "Netmask"
variant string "255.255.255.0"
)
]
signal time=1549641357.696454 sender=:1.3 -> destination=(null destination) serial=496 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "IPv4"
variant array [
dict entry(
string "Method"
variant string "dhcp"
)
dict entry(
string "Address"
variant string "10.0.2.15"
)
dict entry(
string "Netmask"
variant string "255.255.255.0"
)
dict entry(
string "Gateway"
variant string "10.0.2.2"
)
]
想通了!
在我的 XML 文件中,我正在观察的信号是:
<signal name="PropertyChanged">
<arg name="name" type="s" />
<arg name="value" type="v" />
</signal>
尽管我试图弄清楚为什么 freedesktop.org 上的示例回调函数是反向的,但我不得不修改以下内容:
static void on_manager_properties_changed (
GDBusProxy *proxy,
GVariant *changed_properties,
const gchar* const *invalidated_properties,
gpointer user_data);
至:
static void on_manager_properties_changed (
GDBusProxy *proxy,
const gchar* const *invalidated_properties, //(name)
GVariant *changed_properties, //(value)
gpointer user_data);
所以在回调函数中type='s'出现在type='v'之前。在那之后,一切都很好。我想也许无论 freedesktop 的例子正在观察什么信号,都可能是与我想要的不同的信息元素。
为了在 dbus 上设置 Connman 信号回调,我几乎遵循 https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/GDBusProxy.html 上的示例,但是在我的回调函数中:
g_signal_connect(
this->manager_proxy,
"property-changed",
G_CALLBACK(on_manager_properties_changed),
this); //Pass in pointer to self so static function can operate on object.
g_signal_connect(
this->manager_proxy,
"technology-added",
G_CALLBACK(on_manager_tech_added),
this); //Pass in pointer to self so static function can operate on object.
g_signal_connect(
this->manager_proxy,
"technology-removed",
G_CALLBACK(on_manager_tech_removed),
this); //Pass in pointer to self so static function can operate on object
void
CM_InterfaceController::on_manager_properties_changed (
GDBusProxy *proxy,
GVariant *changed_properties,
const gchar* const *invalidated_properties,
gpointer user_data)
{
if(!user_data){CM_ERR("NO THIS * on_manager_properties_changed");return;}
CM_InterfaceController * ths = static_cast<CM_InterfaceController *>(user_data);
std::cout<<"on_manager_properties_changed"<<std::endl;
if(changed_properties){
std::cout<<"children: "<<g_variant_n_children(changed_properties)<<std::endl;
}
}
我被告知 GVariant * object 包含的 children 的数量是完全错误的。比如我的反馈:
Calling Extraction
Service List Size: 1
Identified Ethernet Link:
Path: /net/connman/service/ethernet_0800277d326e_cable
Type: ethernet
Sate: ready
Favorite: 0
Auto Connect: 0
Name: Wired
Net Mode: manual
Iface: eth0
Mac: 08:00:27:7D:32:6E
IP Address: 10.0.2.15
Net Mask: 255.255.255.0
on_manager_properties_changed
children: 139764141513856
on_manager_properties_changed
children: 145
on_manager_properties_changed children: 139764141513856 on_manager_properties_changed children: 145
这两个值都超出了范围,一个比另一个更明显。更重要的是,如果我尝试从 GVariant object 中解析值,即使只是尝试调用 g_variant_get_type_string,我也会出现段错误。 为什么我的回调 return 使用垃圾数据指针? 似乎如果它什么都没有,它至少应该 return 一个空指针。
编辑:Source Code https://drive.google.com/file/d/1E0Kg9JKW54gghUHbVyBJ0ysBIdqBlpVA/view?usp=sharing
还有一些dbus-monitor--系统输出:
signal time=1549641357.679460 sender=:1.3 -> destination=(null destination) serial=488 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "State"
variant string "ready"
signal time=1549641357.680844 sender=:1.3 -> destination=(null destination) serial=489 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "Nameservers"
variant array [
string "10.0.2.3"
]
signal time=1549641357.681186 sender=:1.3 -> destination=(null destination) serial=490 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "Domains"
variant array [
]
signal time=1549641357.681601 sender=:1.3 -> destination=(null destination) serial=491 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "Proxy"
variant array [
dict entry(
string "Method"
variant string "direct"
)
]
signal time=1549641357.681780 sender=:1.3 -> destination=(null destination) serial=492 path=/net/connman/technology/ethernet; interface=net.connman.Technology; member=PropertyChanged
string "Connected"
variant boolean true
signal time=1549641357.682210 sender=:1.3 -> destination=(null destination) serial=493 path=/; interface=net.connman.Manager; member=PropertyChanged
string "State"
variant string "ready"
signal time=1549641357.696004 sender=:1.3 -> destination=(null destination) serial=494 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "IPv4"
variant array [
dict entry(
string "Method"
variant string "dhcp"
)
]
signal time=1549641357.696227 sender=:1.3 -> destination=(null destination) serial=495 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "IPv4"
variant array [
dict entry(
string "Method"
variant string "dhcp"
)
dict entry(
string "Address"
variant string "10.0.2.15"
)
dict entry(
string "Netmask"
variant string "255.255.255.0"
)
]
signal time=1549641357.696454 sender=:1.3 -> destination=(null destination) serial=496 path=/net/connman/service/ethernet_0800277d326e_cable; interface=net.connman.Service; member=PropertyChanged
string "IPv4"
variant array [
dict entry(
string "Method"
variant string "dhcp"
)
dict entry(
string "Address"
variant string "10.0.2.15"
)
dict entry(
string "Netmask"
variant string "255.255.255.0"
)
dict entry(
string "Gateway"
variant string "10.0.2.2"
)
]
想通了!
在我的 XML 文件中,我正在观察的信号是:
<signal name="PropertyChanged">
<arg name="name" type="s" />
<arg name="value" type="v" />
</signal>
尽管我试图弄清楚为什么 freedesktop.org 上的示例回调函数是反向的,但我不得不修改以下内容:
static void on_manager_properties_changed (
GDBusProxy *proxy,
GVariant *changed_properties,
const gchar* const *invalidated_properties,
gpointer user_data);
至:
static void on_manager_properties_changed (
GDBusProxy *proxy,
const gchar* const *invalidated_properties, //(name)
GVariant *changed_properties, //(value)
gpointer user_data);
所以在回调函数中type='s'出现在type='v'之前。在那之后,一切都很好。我想也许无论 freedesktop 的例子正在观察什么信号,都可能是与我想要的不同的信息元素。