打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Windows下dbus的hello world
dbus的是一个低延迟,低开销,高可用性的IPC机制。通过dbus的daemon,可以实现进程间通信和函数调用。Windows下,dbus的开发库可以去这里(http://code.google.com/p/dbus-windows-installer/downloads/list)下载,在VS设置头文件和lib库的路径即可。若是要编写其Hello World,自然包含客户端和服务端两部分。下面的Hello World代码包含了发送消息和函数调用两部分,分别描述之。
1) 信号
假设客户端发送消息,服务端接收。客户端发送消息的流程如下:
1.创建于dbus daemon的会话连接。
2.创建消息,若有消息参数,附加之(这个一般都有)
3.通过连接发送消息。
1: int main (int argc, char *argv[]) 2: { 3: DBusError dberr; 4: DBusConnection *dbconn; 5: DBusMessage *dbmsg; 6: char *text; 7:  8: // 初始话错误信息的结构体 9: dbus_error_init (&dberr); 10: 11: // 创建会话连接 12: dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr); 13: if (dbus_error_is_set (&dberr)) { 14: fprintf (stderr, "getting session bus failed: %s/n", dberr.message); 15: dbus_error_free (&dberr); 16: return EXIT_FAILURE; 17: } 18:  19: // 创建消息 20: dbmsg = dbus_message_new_signal ("/com/wiley/test", 21: "com.wiley.test", 22: "TestSignal"); 23: if (!dbmsg) { 24: fprintf (stderr, "Could not create a new signal/n"); 25: return EXIT_FAILURE; 26: } 27:  28: // 消息中,附加文本 29: text = "Hello World"; 30: if (!dbus_message_append_args ( 31: dbmsg, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID)) { 32: fprintf(stderr, "Out Of Memory!/n"); 33: return EXIT_FAILURE; 34: } 35:  36: // 发送消息 37: if (!dbus_connection_send (dbconn, dbmsg, NULL)) { 38: fprintf(stderr, "Out Of Memory!/n"); 39: return EXIT_FAILURE; 40: } 41: dbus_connection_flush(dbconn); 42:  43: printf ("Sending signal to D-Bus/n"); 44:  45: // 释放消息 46: dbus_message_unref (dbmsg); 47:  48: // 释放会话连接 49: dbus_connection_unref (dbconn); 50:  51: return EXIT_SUCCESS; 52: }
服务端接收消息的流程如下:
1.创建于dbus daemon的会话连接。
2.为本次连接设置名称,客户端可以通过此名称进行通信
3.设置消息对应的回调函数
4.添加消息匹配规则
5.进入处理消息的循环
1: static DBusHandlerResult 2: filter_func (DBusConnection *connection, 3: DBusMessage *message, 4: void *user_data) 5: { 6: dbus_bool_t handled = FALSE; 7: char *signal_text = NULL; 8:  9: // 若为指定信号 10: if (dbus_message_is_signal (message, "com.wiley.test", "TestSignal")) { 11: DBusError dberr; 12: // 初始化错误结构体 13: dbus_error_init (&dberr); 14: // 获取消息的参数 15: dbus_message_get_args (message, &dberr, DBUS_TYPE_STRING, &signal_text, DBUS_TYPE_INVALID); 16: if (dbus_error_is_set (&dberr)) { 17: fprintf (stderr, "Error getting message args: %s", dberr.message); 18: dbus_error_free (&dberr); 19: } else { 20: printf ("Received TestSignal with value of: '%s'/n", signal_text); 21: // 标识本消息已处理 22: handled = TRUE; 23: } 24: } 25: // 返回值决定该消息是否处理 26: return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED); 27: } 28:  29:  30: int main (int argc, char *argv[]) 31: { 32: DBusError dberr; 33: DBusConnection *dbconn; 34:  35: // 初始话错误信息的结构体 36: dbus_error_init (&dberr); 37: 38: // 创建会话 39: dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr); 40: if (dbus_error_is_set (&dberr)) { 41: fprintf (stderr, "getting session bus failed: %s/n", dberr.message); 42: dbus_error_free (&dberr); 43: return EXIT_FAILURE; 44: } 45:  46: // 向daemon追加了一条路由到该应用程序入口 47: dbus_bus_request_name (dbconn, "com.wiley.test", 48: DBUS_NAME_FLAG_REPLACE_EXISTING, &dberr); 49: if (dbus_error_is_set (&dberr)) { 50: fprintf (stderr, "requesting name failed: %s/n", dberr.message); 51: dbus_error_free (&dberr); 52: return EXIT_FAILURE; 53: } 54:  55: // 设置处理消息的函数 56: if (!dbus_connection_add_filter (dbconn, filter_func, NULL, NULL)) { 57: return EXIT_FAILURE; 58: } 59:  60: // 添加消息匹配规则 61: dbus_bus_add_match (dbconn, 62: "type='signal',interface='com.wiley.test'", 63: &dberr); 64: if (dbus_error_is_set (&dberr)) { 65: fprintf (stderr, "Could not match: %s", dberr.message); 66: dbus_error_free (&dberr); 67: return EXIT_FAILURE; 68: } 69:  70: // 分派消息的Loop 71: while (dbus_connection_read_write_dispatch (dbconn, -1)) 72: ; /* empty loop body */ 73:  74: return EXIT_SUCCESS; 75: }
2) 跨进程调用
跨进程调用中,客户端和服务端的流程差不多,假设客户端跨进程调用服务端函数。
客户端
1: int main (int argc, char *argv[]) 2: { 3: DBusMessage* msg; 4: DBusMessageIter args; 5: DBusConnection* conn; 6: DBusError err; 7: DBusPendingCall* pending; 8: char* param = "no param"; 9: int ret; 10: dbus_bool_t stat = FALSE; 11: dbus_uint32_t level = 0; 12:  13: printf("Calling remote method with %s/n", param); 14:  15: // 初始化错误 16: dbus_error_init(&err); 17:  18: // 获取会话连接 19: conn = dbus_bus_get(DBUS_BUS_SESSION, &err); 20: if (dbus_error_is_set(&err)) { 21: fprintf(stderr, "Connection Error (%s)/n", err.message); 22: dbus_error_free(&err); 23: } 24: if (NULL == conn) { 25: exit(1); 26: } 27:  28: // 设置连接名称,若存在则替换 29: ret = dbus_bus_request_name(conn, "test.method.caller", DBUS_NAME_FLAG_REPLACE_EXISTING , &err); 30: if (dbus_error_is_set(&err)) { 31: fprintf(stderr, "Name Error (%s)/n", err.message); 32: dbus_error_free(&err); 33: } 34: if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { 35: exit(1); 36: } 37:  38: // 创建方法调用的消息 39: msg = dbus_message_new_method_call("com.test.dbus.server", // target for the method call 40: "/test/method/Object", // object to call on 41: "test.method.Interface", // interface to call on 42: "Method"); // method name 43: if (NULL == msg) { 44: fprintf(stderr, "Message Null/n"); 45: exit(1); 46: } 47:  48: // 附加参数 49: dbus_message_iter_init_append(msg, &args); 50: if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &param)) { 51: fprintf(stderr, "Out Of Memory!/n"); 52: exit(1); 53: } 54:  55: // 发送消息(-1表示使用默认超时) 56: if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { 57: fprintf(stderr, "Out Of Memory!/n"); 58: exit(1); 59: } 60: if (NULL == pending) { 61: fprintf(stderr, "Pending Call Null/n"); 62: exit(1); 63: } 64:  65: // 阻塞直到发送的消息队列为空 66: dbus_connection_flush(conn); 67:  68: printf("Request Sent/n"); 69:  70: // 释放消息 71: dbus_message_unref(msg); 72:  73: // 阻塞至消息返回 74: dbus_pending_call_block(pending); 75:  76: // 获取返回消息 77: msg = dbus_pending_call_steal_reply(pending); 78: if (NULL == msg) { 79: fprintf(stderr, "Reply Null/n"); 80: exit(1); 81: } 82: 83: // 释放pending 84: dbus_pending_call_unref(pending); 85:  86: // 读取参数 87: if (!dbus_message_iter_init(msg, &args)) 88: fprintf(stderr, "Message has no arguments!/n"); 89: else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args)) 90: fprintf(stderr, "Argument is not boolean!/n"); 91: else 92: dbus_message_iter_get_basic(&args, &stat); 93:  94: if (!dbus_message_iter_next(&args)) 95: fprintf(stderr, "Message has too few arguments!/n"); 96: else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args)) 97: fprintf(stderr, "Argument is not int!/n"); 98: else 99: dbus_message_iter_get_basic(&args, &level); 100:  101: printf("Got Reply: %d, %d/n", stat, level); 102:  103: // 释放方法返回的消息 104: dbus_message_unref(msg); 105:  106: return EXIT_SUCCESS; 107: }
服务端
1: static 2: void reply_to_method_call(DBusMessage* msg, DBusConnection* conn) 3: { 4: DBusMessage* reply; 5: DBusMessageIter args; 6: dbus_bool_t stat = TRUE; 7: dbus_uint32_t level = 21614; 8: dbus_uint32_t serial = 0; 9: char* param = ""; 10:  11: // 读取参数 12: if (!dbus_message_iter_init(msg, &args)) // 获取参数 13: fprintf(stderr, "Message has no arguments!/n"); 14: else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) // 参数类型不为字符串 15: fprintf(stderr, "Argument is not string!/n"); 16: else { // 参数为字符串 17: dbus_message_iter_get_basic(&args, &param); 18: } 19:  20: printf("Method called with %s/n", param); 21:  22: // 创建返回类型的消息,对应于调用的消息 23: reply = dbus_message_new_method_return(msg); 24:  25: // 初始化返回的参数 26: dbus_message_iter_init_append(reply, &args); 27: if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &stat)) { // 附加基本类型的值到消息中 28: fprintf(stderr, "Out Of Memory!/n"); 29: exit(1); 30: } 31: if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &level)) { // 附加基本类型的值到消息中 32: fprintf(stderr, "Out Of Memory!/n"); 33: exit(1); 34: } 35:  36: // 发送返回消息 37: if (!dbus_connection_send(conn, reply, &serial)) { 38: fprintf(stderr, "Out Of Memory!/n"); 39: exit(1); 40: } 41: dbus_connection_flush(conn); 42:  43: // 释放方法返回的消息 44: dbus_message_unref(reply); 45: } 46:  47: int main (int argc, char *argv[]) 48: { 49: DBusError dberr; 50: DBusConnection * dbconn; 51: DBusMessage * msg; 52: int ret; 53:  54: // 初始话错误信息的结构体 55: dbus_error_init (&dberr); 56: // 创建会话 57: dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr); 58: if (dbus_error_is_set (&dberr)) { 59: fprintf (stderr, "getting session bus failed: %s/n", dberr.message); 60: dbus_error_free (&dberr); 61: return EXIT_FAILURE; 62: } 63:  64: // 为本次连接设置名称,客户端可以通过此名称进行通信 65: ret = dbus_bus_request_name (dbconn, "com.test.dbus.server", 66: DBUS_NAME_FLAG_REPLACE_EXISTING, &dberr); 67: if (dbus_error_is_set (&dberr)) { 68: fprintf (stderr, "requesting name failed: %s/n", dberr.message); 69: dbus_error_free (&dberr); 70: return EXIT_FAILURE; 71: } 72: if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { 73: fprintf(stderr, "Not Primary Owner (%d)/n", ret); 74: exit(1); 75: } 76:  77: // 循环等待消息 78: while (true) { 79: // 非阻塞的获取下一个消息 80: // TODO: 如何阻塞? 81: dbus_connection_read_write(dbconn, 0); 82:  83: // 获取消息 84: msg = dbus_connection_pop_message(dbconn); 85: if (NULL == msg) { 86: // sleep(1); 87: continue; 88: } 89:  90: // 相应消息调用 91: if (dbus_message_is_method_call(msg, "test.method.Interface", "Method")) 92: reply_to_method_call(msg, dbconn); 93:  94: // 释放引用 95: dbus_message_unref(msg); 96: } 97:  98: return EXIT_SUCCESS; 99: }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
dbus入门与应用 dbus c编程接口
linux使用dbus
D-Bus学习(五):Signal的收发小例子
Qt浅谈之二十七进程间通信之QtDBus good
Linux下的进程通信(IPC) --晃晃悠悠
linux消息队列操作
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服