如何编组 dbus 字符串数组 (ao) 类型?

Posted

技术标签:

【中文标题】如何编组 dbus 字符串数组 (ao) 类型?【英文标题】:How to marshal dbus string array (ao) type? 【发布时间】:2014-10-19 16:24:24 【问题描述】:

我正在使用 gdbus 绑定。这是我的界面的一部分:

<node>
    <interface name="USB.Manager">
        <property name="Devices" type="ao" access="read">
             <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
        </property>
    </interface>
</node>

我未能从该接口提取设备列表获取到字符串数组。谁能告诉 dbus 字符串数组的正确编组?

我对dbus字符串数组结构的假设如下:

|--------|--------|--------|--------|
|         array length              |
|        pointer to first string    |
|       pointer to second string    |

字符串的内部结构如下:

|--------|--------|--------|--------|
|        string length              |
|   char |  char  |  char  | char   |
|            ......                 |
|  char  | '\0'   |        |        |

下面是我的代码:

static USBManager *pSkeletonManager = usbmanager_skeleton_new();

gchar* deviceList[2] =  "/dev/obj/usb1", "/dev/obj/usb2" ;
gchar* aoList[255];
ConvertStringArrayToAo(deviceList, aoList, 2);

usbmanager_set_devices(pSkeletonManager, aoList);

void ConvertStringArrayToAo(char** stringArray, char** aoString, int length)

    if (length == 0)
    
        return;
    

    // Array - leading length
    aoString[0] = (char*)length;

    g_print("Length: %d, aoString[0]: %d\n", length, aoString[0]);

    // Array - content
    int i = 0;
    for (; i < length; i++)
    
        char* string = stringArray[i];
        char* resultString = aoString[i+1];

        // 4 byte for leading length
        // 1 byte for terminating \0
        aoString[i+1] = (char*)malloc(strlen(string) + 5);
        memset(aoString[i+1], 0, strlen(string)+5);

        // length
        int j = 0;
        aoString[i+1][0] = (strlen(string) & 0xF000) >> 24;
        aoString[i+1][1] = (strlen(string) & 0x0F00) >> 16;
        aoString[i+1][2] = (strlen(string) & 0x00F0) >> 8;
        aoString[i+1][3] = (strlen(string) & 0x000F);

        // content
        strncpy(&aoString[i+1][4], string, strlen(string));

        // terminating
        aoString[i+1][strlen(string)+4] = '\0';

        g_print("%s\n", &aoString[i+1][4]);
    

这段代码在调用“usbmanager_set_devices”时遇到分段错误。

【问题讨论】:

其实我的问题走错路了。我根本不需要编组 dbus 字符串数组。只需设置usbmanager_set_devices(pSkeletonManager, device_list); 即可。 请关闭这个问题。 【参考方案1】:

我尝试使用我的 node.js dbus-native 客户端库来序列化您的示例

这是我的代码:

var marshall = require('dnus-native/lib/marshall')
console.log( marshall('ao', [ ["/dev/obj/usb1", "/dev/obj/usb2"] ], 0) );

输出:

<Buffer 26 00 00 00 0d 00 00 00 2f 64 65 76 2f 6f 62 6a 2f 75 73 62 31 00 00 00 0d 00 00 00 2f 64 65 76 2f 6f 62 6a 2f 75 73 62 32 00>

注意长度前缀need to be aligned to a 4 byte boundary(如果需要,字符串用零填充)。尝试在我的示例中将您的 aoString 与缓冲区进行比较

【讨论】:

您的编组示例可能不适合 gdbus。 API“usbmanager_set_devices”接受设备为“char**”,这是一个字符指针数组。 在线级别上只有基本类型被序列化 - ints/floats/strings。您不能将指针发送到另一个进程

以上是关于如何编组 dbus 字符串数组 (ao) 类型?的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 dbus:强制信号参数的类型签名为字符串数组

dbus中的数据类型

如何定义和编组 BSTR* 类型

如何在 PyQt5 中将字符串数组传递给 dbus? [复制]

如何在 C# 中编组数据类型 unsigned char**?

如何确定 DBus 消息中“结构数组”的长度?