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)信号
クライアントがメッセージを送信すると仮定して、サービス端末が受信する.クライアントがメッセージを送信する流れは以下の通りです.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, ¶m)) {
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, ¶m);
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: }