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)