D-Bus创建复合签名属性失败:sd_bus_add_object_vtable返回-22
sd_bus_add_object_vtable返回-EINVAL的问题分析与解决
我帮你排查了代码里的问题,导致sd_bus_add_object_vtable返回-22(-EINVAL)的主要原因有两个:
1. 属性回调函数的返回值错误
你的get_property_cb函数最后返回了1,但systemd的sd-bus框架要求属性获取回调必须返回0表示成功,任何非0值都会被判定为操作失败。这个错误会导致vtable验证不通过,进而让sd_bus_add_object_vtable返回无效参数错误。
2. 手动创建容器导致签名不匹配
你的属性签名是"ii"(代表两个连续的有符号整数,本质是一个D-Bus元组类型),但你在回调里手动调用了sd_bus_message_open_container创建了一个'r'类型的容器,然后分别追加两个int,最后关闭容器。这相当于你实际发送的数据签名是"(ii)"(嵌套元组),和属性声明的"ii"不匹配,这也是触发EINVAL的关键原因。
修改后的代码
只需要调整get_property_cb函数,去掉手动容器管理,直接用完整签名追加数据,同时返回正确的状态码:
static int get_property_cb(sd_bus*_bus, const char* path, const char* interface, const char* property, sd_bus_message* reply, void* userdata, sd_bus_error* ret_error) { // 直接使用属性的完整签名追加数据,sd_bus_message_append会自动处理复合类型的容器 return sd_bus_message_append(reply, DATA_SIGNATURE, 111, 222); }
另外,建议你把vtable数组的长度声明去掉,让编译器自动计算,避免因为条目数变化导致数组越界:
static const sd_bus_vtable prop_spec[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY(DATA_PROPERTY, DATA_SIGNATURE, get_property_cb, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_VTABLE_END };
其他注意事项
- 配置文件
com.myexample.myproject.conf放在/etc/dbus-1/system.d/是更标准的自定义服务配置位置,/usr/share/dbus-1/system.d/一般存放系统默认的配置。 - 运行程序前,确保dbus-daemon已经加载了你的接口文件和配置,你可以重启dbus服务(
systemctl restart dbus)来确保配置生效。
修改后重新编译运行,sd_bus_add_object_vtable应该就能成功返回0了。
内容的提问来源于stack exchange,提问作者pav22222
相关产品推荐
相关产品推荐

