Windows下、dbusのハローワールド

39117 ワード

dbusは低遅延、低オーバーヘッド、高利用性のIPC機構である.dbusのdaemenを通じて、プロセス間通信と関数呼び出しが可能です.Windowsの下で、dbusの開発庫はここに行けます.http://code.google.com/p/dbus-windows-installer/downloads/list)をダウンロードし、VSにヘッダファイルとlibライブラリのパスを設定すればいいです.そのハローワールドを編纂するなら、クライアントとサービス端末の二つの部分が自然に含まれます.以下のハローワールドコードは、送信メッセージと関数呼び出しの2つの部分を含み、それぞれ説明されています.
      1)信号
クライアントがメッセージを送信すると仮定して、サービス端末が受信する.クライアントがメッセージを送信する流れは以下の通りです.1.dbus daemenでセッション接続を作成します.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 daemenで作成されたセッション接続.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: }