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 " % (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
* @date 2012/03/22 10:51:21
*/
#include
#include
#include
#include
#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 \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)