DBus glib 各數據類型接收與發送詳解—C語言(1)

DBus glib 各數據類型接收與發送詳解—C語言(1)

動機

說到 DBus 用過的人大概都能明白其工作的流程。典型的使用流程是,向 DBus 服務進程發送數據,然後接收其返回的數據。簡單的說,就像調用函數一樣,向服務進程發送數據就相當於函數的參數,其返回的數據就相當於函數返回的結果。雖然明白了流程,但想要使用 C語言 通過已有的 DBus 服務進行操作,仍然是一項不太容易的工作(對像我這樣的菜鳥^_^),因爲數據的類型真是太多了, 使用 Python 會簡單一點。簡單點的有 Boolean, Byte, Int32, Int64, String, ObjectPath, Signature 等; 複雜一點的有 Array, Struct, Dict 等。如果不能弄清楚它們之間的聯繫,那麼將是一件非常頭痛的事。爲了使我研究的結果不被淡忘,於是有了這篇文章。

前置知識

  • 能夠熟練使用 C語言;
  • 瞭解 DBus 各數據類型的表示, 參考 D-Bus Specification
  • 對 DBus-glib 有基本的瞭解,能夠與 DBus 服務進程進行簡單的交互。
  • 簡單使用 d-feet, 參考 D-Bus 實例講解
  • 大概對 Python 有些瞭解(只是爲了說明我的分析思路,如果你只想找 C 的解決方法,那完全可以不瞭解);
  • 簡單瞭解 python dbus

正文

對了,編譯的時候要加上 dbus-glib 庫,在本篇的最後會給出一個 Makefile 文件,把它放到要編譯的文件的目錄下,直接 make 應該就可以了,感覺說的不清楚,不過懂的話應該是懂的(-_-b)

Python DBus 的簡單演示

 

Python DBus 服務進程

使用 Python 編寫 DBus 服務進程是比較舒心的一件事。那麼廢話不多說,先來一個 "1+1=2" 的例子 (**oneonetwo_service.py**)。


#!/usr/bin/env python

import gobject

import dbus
import dbus.service
import dbus.mainloop.glib

class Example(dbus.service.Object):
    def __init__(self, bus, object_path):
        dbus.service.Object.__init__(self, bus, object_path)
        self._last_input = None

    @dbus.service.method('airead.fan.Example', in_signature='ii', out_signature='i')
    def IntArrayPrint(self, num1, num2):
        print "receive:", num1, num2
        return num1 + num2

if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    session_bus = dbus.SessionBus()
    name = dbus.service.BusName("airead.fan.Example", session_bus)
    object = Example(session_bus, '/airead/fan/Example')

    mainloop = gobject.MainLoop()
    print "Running example service."
    mainloop.run()


簡單說明一下關鍵點:

  • @dbus.service.method('airead.fan.Example', in_signature='ii', out_signature='i') 聲明瞭一個 DBus 服務進程的一個方法,其中 airead.fan.Example 是接口, in_signature='ii' 說明該方法需要兩個輸入參數且者爲 Int32 類型, out_signature='i' 說明該方法會輸出一個參數且爲 Int32 類型。
  • def IntArrayPrint(self, num1, num2): 定義了接收到2個參數後的處理函數
  • name = dbus.service.BusName("airead.fan.Example", session_bus) 取得 DBus 的 well-known Bus name
  • object = Example(session_bus, '/airead/fan/Example') 將定義的 class Example 註冊到 DBus 上。

調用 DBus 服務進程的方法

調用方法: oneonetwo_client.py


#!/usr/bin/python

import sys
import dbus
from traceback import print_exc

def main():

    # get Session Bus
    bus = dbus.SessionBus()

    # get remote ojbect
    remote_object = bus.get_object("airead.fan.Example", "/airead/fan/Example")

    # get D-Bus Interface
    dbus_interface = dbus.Interface(remote_object, "airead.fan.Example")

    # call Example method
    ret = dbus_interface.Example(1, 1)
    print "result:", ret

main()

看註釋基本就可以了。

給 .py 添加可執行權限,先運行 service ,再運行 client 看結果,記得開兩個shell。

所有基本數據類型演示

簡單說一下我的思路,因爲 D-Bus, glib 和 DBus-glib binding 中數據的類型真的是太多了,而我又沒有系統的研究過它們三者的任何一個,所以各種數據類型的傳遞都是一點一點來試驗的。因爲 Python 使用起來簡單,能夠保證程序的正確性,我都是先用 Python 編寫滿足條件的 D-Bus 服務進程,再用 Python 編寫該服務進程的測試用例,最後纔開始使用C語言來發送和接收各種數據類型。所以後面就不對 Python 進行解釋,直接分析 C 代碼。

基本數據類型服務進程 (py)

 

all_basic_data_deliver_service.py


#!/usr/bin/env python

import gobject

import dbus
import dbus.service
import dbus.mainloop.glib

class BasicData(dbus.service.Object):
    def __init__(self, bus, object_path):
        dbus.service.Object.__init__(self, bus, object_path)
        self._last_input = None

    @dbus.service.method('airead.fan.BasicDataType', in_signature='y', out_signature='y')
    def BytePrint(self, byte):
        print "receive byte:", byte
        return byte + 1

    @dbus.service.method('airead.fan.BasicDataType', in_signature='b', out_signature='b')
    def BooleanPrint(self, boolean):
        print "receive boolean:", boolean
        return not boolean

    @dbus.service.method('airead.fan.BasicDataType', in_signature='n', out_signature='n')
    def Int16Print(self, int16):
        print "receive int16:", int16
        return int16 + 1

    @dbus.service.method('airead.fan.BasicDataType', in_signature='q', out_signature='q')
    def Uint16Print(self, uint16):
        print "receive uint16:", uint16
        return uint16 + 1

    @dbus.service.method('airead.fan.BasicDataType', in_signature='i', out_signature='i')
    def Int32Print(self, int32):
        print "receive int32:", int32
        return int32 + 1

    @dbus.service.method('airead.fan.BasicDataType', in_signature='u', out_signature='u')
    def Uint32Print(self, uint32):
        print "receive uint32:", uint32
        return uint32 + 1

    @dbus.service.method('airead.fan.BasicDataType', in_signature='x', out_signature='x')
    def Int64Print(self, int64):
        print "receive int64:", int64
        return int64 + 1

    @dbus.service.method('airead.fan.BasicDataType', in_signature='t', out_signature='t')
    def Uint64Print(self, uint64):
        print "receive uint64:", uint64
        return uint64 + 1

    @dbus.service.method('airead.fan.BasicDataType', in_signature='d', out_signature='d')
    def DoublePrint(self, double):
        print "receive double:", double
        return double + 1.5

    @dbus.service.method('airead.fan.BasicDataType', in_signature='s', out_signature='s')
    def StringPrint(self, string):
        print "receive string:", string
        return string + "echo"

    @dbus.service.method('airead.fan.BasicDataType', in_signature='o', out_signature='o')
    def ObjectpathPrint(self, objectpath):
        print "receive objectpath:", objectpath
        return dbus.ObjectPath(objectpath + "_return")

    @dbus.service.method('airead.fan.BasicDataType', in_signature='g', out_signature='g')
    def SignaturePrint(self, signature):
        print "receive signature:", signature
        return signature + "s"

if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    session_bus = dbus.SessionBus()
    name = dbus.service.BusName("airead.fan.BasicDataType", session_bus)
    object = BasicData(session_bus, '/airead/fan/BasicDataType')

    mainloop = gobject.MainLoop()
    print "Running example service."
    mainloop.run()

Python DBus 測試代碼

all_basic_data_deliver_client.py


#!/usr/bin/python

import sys
import dbus
from traceback import print_exc

def main():

    bus = dbus.SessionBus()
    method = sys.argv[1] + "Print"

    value = sys.argv[2]

    if sys.argv[1] == "Signature":
        value = dbus.Signature(value)
    elif sys.argv[1] == "Objectpath":
        value = dbus.ObjectPath(value)
    elif sys.argv[1] != "Byte" and sys.argv[1] != "Objectpath" and sys.argv[1] != "String":
        value = eval(value)

    try:
        remote_object = bus.get_object("airead.fan.BasicDataType", "/airead/fan/BasicDataType")
        dbus_interface = dbus.Interface(remote_object, "airead.fan.BasicDataType")
        method_call = dbus_interface.get_dbus_method(method);
        ret = method_call(value)
        print ret

    except dbus.DBusException:
        print_exc()
        sys.exit(1)


if __name__ == '__main__':
    if (len(sys.argv) < 3):
	print "Usage: %s <data_type> <data_value>" % (sys.argv[0])
	sys.exit(1)

main()

我還寫了一個比較料的 shell 腳本用來全面的進行測試。 all_basic_data_deliver_test_py.sh


#!/bin/sh

echo ./all_basic_data_deliver_client.py Boolean False
./all_basic_data_deliver_client.py Boolean False
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Byte f
./all_basic_data_deliver_client.py Byte f
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Double 3.2
./all_basic_data_deliver_client.py Double 3.2
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Int16 4
./all_basic_data_deliver_client.py Int16 4
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Int32 4
./all_basic_data_deliver_client.py Int32 4
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Int64 2
./all_basic_data_deliver_client.py Int64 2
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Objectpath "/object"
./all_basic_data_deliver_client.py Objectpath "/object"
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Signature i
./all_basic_data_deliver_client.py Signature i
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py String String
./all_basic_data_deliver_client.py String String
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Uint32 99
./all_basic_data_deliver_client.py Uint32 99
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Uint64 33
./all_basic_data_deliver_client.py Uint64 33
echo -e "=================================\n"
echo ./all_basic_data_deliver_client.py Uint16 35
./all_basic_data_deliver_client.py Uint16 35
echo -e "=================================\n"

使用 C 實現基本數據類型的傳遞

使用 C 來進行基本數據類型的傳遞還是比較簡單的。大概可以分爲兩類:傳遞 實體(也就是沒有用指針表示) 與 傳遞 指針(也就是使用指針表示)。說得也不是很清楚,舉個例子,就像你定義一個字符是用 char c = 'b'; 定義一個字符串是用 char str = "AireadFan" 的區別一樣。

Boolean, byte, int*, uint** 等屬於 實體; String, ObjectPath, Signature 屬於 指針 。下面是具體代碼,最後會給出整個測試代碼及 shell 腳本。

Boolean

Boolean: glib->gboolean, G_TYPE_BOOLEAN; D-Bus->'b';

解釋一下,就是說 Boolean 類型,在 D-Bus glib binding 中使用 gboolean 聲名,在使用類似 dbus_g_proxy_call() 函數傳遞參數時使用 G_TYPE_BOOLEAN, 在服務進程或 XML 聲名時使用 'b'。 注意:以後將不再進行說明!

那麼來看一下 Boolean 是怎麼傳遞的吧。


int send_recv_boolean(DBusGProxy *proxy, char *method, char *value)
{
    gboolean bool, ret;
    GError *error = NULL;

    if (!strcmp(value, "False")) {
        bool = FALSE;
    } else {
        bool = TRUE;
    }
    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_BOOLEAN, bool,
                           G_TYPE_INVALID,
                           G_TYPE_BOOLEAN, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %d\n", ret);

    return 0;
}
Byte

Byte: glib->guchar, G_TYPE_UCHAR, dbus->'y'



int send_recv_byte(DBusGProxy *proxy, char *method, char *value)
{
    guchar byte, ret;
    GError *error = NULL;

    byte = value[0];

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_UCHAR, byte,
                           G_TYPE_INVALID,
                           G_TYPE_UCHAR, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %c\n", ret);

    return 0;
}
Double

Double: glib->gdouble, G_TYPE_DOUBLE, dbus->'d'


int send_recv_double(DBusGProxy *proxy, char *method, char *value)
{
    gdouble d, ret;
    GError *error = NULL;

    //double strtod(const char *nptr, char **endptr);
    d = strtod(value, NULL);

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_DOUBLE, d,
                           G_TYPE_INVALID,
                           G_TYPE_DOUBLE, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %f\n", ret);

    return 0;
}

Int

Int32: glib->gint32, G_TYPE_INT, dbus->'i'

這裏要說明的是: int16, int32, int64, uint16, uint32, uint64 之間幾乎都是一樣的,困難不大。



int send_recv_int32(DBusGProxy *proxy, char *method, char *value)
{
    gint32 int32, ret;
    GError *error = NULL;

    int32 = strtol(value, NULL, 10);

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_INT, int32,
                           G_TYPE_INVALID,
                           G_TYPE_INT, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %d\n", ret);

    return 0;
}
String

String: glib->gchar *, G_TYPE_STRING, dbus->'s'



int send_recv_string(DBusGProxy *proxy, char *method, char *value)
{
    gchar *str, *ret;
    GError *error = NULL;

    str = value;

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_STRING, str,
                           G_TYPE_INVALID,
                           G_TYPE_STRING, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %s\n", ret);

    return 0;
}

ObjectPath

ObjectPath: glib->DBusGObjectPath *, DBUS_TYPE_G_OBJECT_PATH, dbus->'o'


int send_recv_objectpath(DBusGProxy *proxy, char *method, char *value)
{
    //typedef gchar DBusGObjectPath;
    const DBusGObjectPath *path, *ret;
    GError *error = NULL;

    path = value;

    if (!dbus_g_proxy_call(proxy, method, &error,
                           DBUS_TYPE_G_OBJECT_PATH, path,
                           G_TYPE_INVALID,
                           DBUS_TYPE_G_OBJECT_PATH, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }

    printf("receive %s\n", ret);

    return 0;
}
Signature

Signature: glib->DBusGSignature *, DBUS_TYPE_G_SIGNATURE, dbus->'g'



int send_recv_signature(DBusGProxy *proxy, char *method, char *value)
{
    //typedef gchar DBusGSignature;
    DBusGSignature *signature, *ret;
    GError *error = NULL;

    signature = value;

    if (!dbus_g_proxy_call(proxy, method, &error,
                           DBUS_TYPE_G_SIGNATURE, signature,
                           G_TYPE_INVALID,
                           DBUS_TYPE_G_SIGNATURE, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %s\n", ret);

    return 0;
}

C D-Bus 測試完整代碼及腳本

all_basic_data_deliver_client.c


/**
 * @file all_basic_data_deliver_client.c
 * @brief
 * @author Airead Fan <[email protected]>
 * @date 2012/03/22 10:51:21
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus-glib.h>

#define METHOD_STRLEN 128

int send_recv_boolean(DBusGProxy *proxy, char *method, char *value)
{
    gboolean bool, ret;
    GError *error = NULL;

    if (!strcmp(value, "False")) {
        bool = FALSE;
    } else {
        bool = TRUE;
    }
    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_BOOLEAN, bool,
                           G_TYPE_INVALID,
                           G_TYPE_BOOLEAN, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %d\n", ret);

    return 0;
}

int send_recv_byte(DBusGProxy *proxy, char *method, char *value)
{
    guchar byte, ret;
    GError *error = NULL;

    byte = value[0];

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_UCHAR, byte,
                           G_TYPE_INVALID,
                           G_TYPE_UCHAR, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %c\n", ret);

    return 0;
}

int send_recv_double(DBusGProxy *proxy, char *method, char *value)
{
    gdouble d, ret;
    GError *error = NULL;

    //double strtod(const char *nptr, char **endptr);
    d = strtod(value, NULL);

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_DOUBLE, d,
                           G_TYPE_INVALID,
                           G_TYPE_DOUBLE, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %f\n", ret);

    return 0;
}

int send_recv_int16(DBusGProxy *proxy, char *method, char *value)
{
    gint16 int16, ret;
    GError *error = NULL;

    int16 = strtol(value, NULL, 10);

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_INT, int16,
                           G_TYPE_INVALID,
                           G_TYPE_INT, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %d\n", ret);

    return 0;
}

int send_recv_int32(DBusGProxy *proxy, char *method, char *value)
{
    gint32 int32, ret;
    GError *error = NULL;

    int32 = strtol(value, NULL, 10);

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_INT, int32,
                           G_TYPE_INVALID,
                           G_TYPE_INT, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %d\n", ret);

    return 0;
}

int send_recv_int64(DBusGProxy *proxy, char *method, char *value)
{
    gint64 int64, ret;
    GError *error = NULL;

    int64 = strtol(value, NULL, 10);

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_INT64, int64,
                           G_TYPE_INVALID,
                           G_TYPE_INT64, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %ld\n", (long)ret);

    return 0;
}

int send_recv_objectpath(DBusGProxy *proxy, char *method, char *value)
{
    //typedef gchar DBusGObjectPath;
    const DBusGObjectPath *path, *ret;
    GError *error = NULL;

    path = value;

    if (!dbus_g_proxy_call(proxy, method, &error,
                           DBUS_TYPE_G_OBJECT_PATH, path,
                           G_TYPE_INVALID,
                           DBUS_TYPE_G_OBJECT_PATH, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }

    printf("receive %s\n", ret);

    return 0;
}

int send_recv_signature(DBusGProxy *proxy, char *method, char *value)
{
    //typedef gchar DBusGSignature;
    DBusGSignature *signature, *ret;
    GError *error = NULL;

    signature = value;

    if (!dbus_g_proxy_call(proxy, method, &error,
                           DBUS_TYPE_G_SIGNATURE, signature,
                           G_TYPE_INVALID,
                           DBUS_TYPE_G_SIGNATURE, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %s\n", ret);

    return 0;
}

int send_recv_string(DBusGProxy *proxy, char *method, char *value)
{
    gchar *str, *ret;
    GError *error = NULL;

    str = value;

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_STRING, str,
                           G_TYPE_INVALID,
                           G_TYPE_STRING, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %s\n", ret);

    return 0;
}

int send_recv_uint32(DBusGProxy *proxy, char *method, char *value)
{
    guint32 uint32, ret;
    GError *error = NULL;

    uint32 = strtoul(value, NULL, 10);

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_UINT, uint32,
                           G_TYPE_INVALID,
                           G_TYPE_UINT, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %u\n", ret);

    return 0;
}

int send_recv_uint64(DBusGProxy *proxy, char *method, char *value)
{
    guint64 uint64, ret;
    GError *error = NULL;

    uint64 = strtoul(value, NULL, 10);

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_UINT64, uint64,
                           G_TYPE_INVALID,
                           G_TYPE_UINT64, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %lu\n", (unsigned long)ret);

    return 0;
}

int send_recv_uint16(DBusGProxy *proxy, char *method, char *value)
{
    guint16 uint16, ret;
    GError *error = NULL;

    uint16 = strtoul(value, NULL, 10);

    if (!dbus_g_proxy_call(proxy, method, &error,
                           G_TYPE_UINT, uint16,
                           G_TYPE_INVALID,
                           G_TYPE_UINT, &ret,
                           G_TYPE_INVALID)) {
        g_printerr("call %s failed: %s\n", method, error->message);
        g_error_free(error);
        error = NULL;
        return -1;
    }
    printf("receive %u\n", ret);

    return 0;
}

int main(int argc, char *argv[])
{
    DBusGConnection *connection;
    GError *error = NULL;
    DBusGProxy *proxy;
    char *type, *value;
    char method[METHOD_STRLEN];

    if (argc < 3) {
        fprintf(stderr, "usage: %s <data_type> <data_value>\n", argv[0]);
        exit(1);
    }

    g_type_init();

    type = argv[1];
    value = argv[2];

    /* conect system connection and get proxy */
    connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
    if (connection == NULL) {
        g_printerr("get system bus failed: %s\n", error->message);
        g_error_free(error);
        return -1;
    }

    /* get proxy */
    proxy = dbus_g_proxy_new_for_name(connection,
                                      "airead.fan.BasicDataType",
                                      "/airead/fan/BasicDataType",
                                      "airead.fan.BasicDataType");

    snprintf(method, METHOD_STRLEN, "%sPrint", type);

    if (!strcmp(type, "Boolean")) { /* gboolean */
        send_recv_boolean(proxy, method, value);
    }else if (!strcmp(type, "Byte")) { /* guchar */
        send_recv_byte(proxy, method, value);
    }else if (!strcmp(type, "Double")) {
        send_recv_double(proxy, method, value);
    }else if (!strcmp(type, "Int16")) {
        send_recv_int16(proxy, method, value);
    }else if (!strcmp(type, "Int32")) {
        send_recv_int32(proxy, method, value);
    }else if (!strcmp(type, "Int64")) {
        send_recv_int64(proxy, method, value);
    }else if (!strcmp(type, "Objectpath")) {
        send_recv_objectpath(proxy, method, value);
    }else if (!strcmp(type, "Signature")) {
        send_recv_signature(proxy, method, value);
    }else if (!strcmp(type, "String")) {
        send_recv_string(proxy, method, value);
    }else if (!strcmp(type, "Uint32")) {
        send_recv_uint32(proxy, method, value);
    }else if (!strcmp(type, "Uint64")) {
        send_recv_uint64(proxy, method, value);
    }else if (!strcmp(type, "Uint16")) {
        send_recv_uint16(proxy, method, value);
    }

    return 0;
}

測試腳本:


#!/bin/sh

echo ./all_basic_data_deliver_client Boolean False
./all_basic_data_deliver_client Boolean False
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Byte f
./all_basic_data_deliver_client Byte f
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Double 3.2
./all_basic_data_deliver_client Double 3.2
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Int16 4
./all_basic_data_deliver_client Int16 4
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Int32 4
./all_basic_data_deliver_client Int32 4
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Int64 2
./all_basic_data_deliver_client Int64 2
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Objectpath "/object"
./all_basic_data_deliver_client Objectpath "/object"
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Signature i
./all_basic_data_deliver_client Signature i
echo -e "=================================\n"
echo ./all_basic_data_deliver_client String String
./all_basic_data_deliver_client String String
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Uint32 99
./all_basic_data_deliver_client Uint32 99
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Uint64 33
./all_basic_data_deliver_client Uint64 33
echo -e "=================================\n"
echo ./all_basic_data_deliver_client Uint16 35
./all_basic_data_deliver_client Uint16 35
echo -e "=================================\n"

Makefile

有些東西實際上沒用,我也懶得去了。


CC	= gcc

CFLAGS	= -Wall -g
CFLAGS += $(shell pkg-config --cflags glib-2.0 )
CFLAGS += $(shell pkg-config --cflags dbus-glib-1)
#CFLAGS += $(shell pkg-config --cflags gtk+-2.0)

LDFLAGS	=
LDFLAGS += $(shell pkg-config --libs glib-2.0)
LDFLAGS += $(shell pkg-config --libs dbus-glib-1)
#LDFLAGS += $(shell pkg-config --libs gtk+-2.0)

SOURCE =  $(wildcard *.c)
TARGETS	:= $(patsubst %.c, %, $(SOURCE))
TARGETS_OUT = common_marshaler basic_data
TARGETS := $(filter-out $(TARGETS_OUT), $(TARGETS))
TARGETS := $(addsuffix .out, $(TARGETS))

%.out: %.c
	@echo CC $< -o $@
	@$(CC) $< common_marshaler.c basic_data.c $(CFLAGS) -o $@ $(LDFLAGS)

.PHONY: all clean test marshaler

all: $(TARGETS)

marshaler:
	glib-genmarshal --prefix _common_marshal --header common_marshaler.list > common_marshaler.h
	glib-genmarshal --prefix _common_marshal --body common_marshaler.list > common_marshaler.c
	dbus-binding-tool --prefix=airead_fan --mode=glib-server all_basic_data_deliver_server.xml > all_basic_data_deliver_server.h

clean:
	rm -f *~ a.out *.o $(TARGETS) core.*

test:
	@echo TARGETS: $(TARGETS)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章