dbus 初探 版本 dbus-1.4.0
来源:互联网 发布:女程序员容易老吗 编辑:程序博客网 时间:2024/05/21 05:23
dbus 初探 版本 dbus-1.4.0
转载时请注明出处和作者联系方式
文章出处:http://www.lt-net.cn
作者联系方式:刘敏 <qtgirl666@gmail.com>
编译系统Ubuntu10.04(确保/opt 可写)交叉编译器arm-linux-gcc 4.3.3硬件设备LT2440开发板 测试软件dbus-1.4.0依赖库libxml2-2.7.6
一直以来都想学习dbus,想把dbus移植到LT2440开发板上,今天弱弱的看了一下相关的资料,编译了dbus库,并且做了一个测试。
首先,编译 libxml2-2.7.6
$ ./configure --host=arm-linux --prefix=/opt/gtkfb
$ make
$ make install
其次,编译dbus-1.4.0
需要先让dbus找到 libxml 库,使用PKG_CONFIG_PATH,使用下面的export 命令即可
$ export PKG_CONFIG_PATH=/opt/gtkfb/lib/pkgconfig
$ ./configure --host=arm-linux --prefix=/opt/gtkfb --without-x --with-xml=libxml
$ make
$ make install
这样dbus库就编译好了,并且会得到一些命令,在/opt/gtkfb/bin目录下,以dbus开头
将相关库拷贝到文件系统,拷贝以上命令到bin目录,已经移植好了,找一个程序做测试
sample.c
- /*
- * Example low-level D-Bus code.
- * Written by Matthew Johnson <dbus@matthew.ath.cx>
- *
- * This code has been released into the Public Domain.
- * You may do whatever you like with it.
- */
- #include <dbus/dbus.h>
- #include <stdbool.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- /**
- * Connect to the DBUS bus and send a broadcast signal
- */
- void sendsignal(char* sigvalue)
- {
- DBusMessage* msg;
- DBusMessageIter args;
- DBusConnection* conn;
- DBusError err;
- int ret;
- dbus_uint32_t serial = 0;
- printf("Sending signal with value %s/n", sigvalue);
- // initialise the error value
- dbus_error_init(&err);
- // connect to the DBUS system bus, and check for errors
- conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Connection Error (%s)/n", err.message);
- dbus_error_free(&err);
- }
- if (NULL == conn) {
- exit(1);
- }
- // register our name on the bus, and check for errors
- ret = dbus_bus_request_name(conn, "test.signal.source", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Name Error (%s)/n", err.message);
- dbus_error_free(&err);
- }
- if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
- exit(1);
- }
- // create a signal & check for errors
- msg = dbus_message_new_signal("/test/signal/Object", // object name of the signal
- "test.signal.Type", // interface name of the signal
- "Test"); // name of the signal
- if (NULL == msg)
- {
- fprintf(stderr, "Message Null/n");
- exit(1);
- }
- // append arguments onto signal
- dbus_message_iter_init_append(msg, &args);
- if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) {
- fprintf(stderr, "Out Of Memory!/n");
- exit(1);
- }
- // send the message and flush the connection
- if (!dbus_connection_send(conn, msg, &serial)) {
- fprintf(stderr, "Out Of Memory!/n");
- exit(1);
- }
- dbus_connection_flush(conn);
- printf("Signal Sent/n");
- // free the message
- dbus_message_unref(msg);
- }
- /**
- * Call a method on a remote object
- */
- void query(char* param)
- {
- DBusMessage* msg;
- DBusMessageIter args;
- DBusConnection* conn;
- DBusError err;
- DBusPendingCall* pending;
- int ret;
- bool stat;
- dbus_uint32_t level;
- printf("Calling remote method with %s/n", param);
- // initialiset the errors
- dbus_error_init(&err);
- // connect to the system bus and check for errors
- conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Connection Error (%s)/n", err.message);
- dbus_error_free(&err);
- }
- if (NULL == conn) {
- exit(1);
- }
- // request our name on the bus
- ret = dbus_bus_request_name(conn, "test.method.caller", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Name Error (%s)/n", err.message);
- dbus_error_free(&err);
- }
- if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
- exit(1);
- }
- // create a new method call and check for errors
- msg = dbus_message_new_method_call("test.method.server", // target for the method call
- "/test/method/Object", // object to call on
- "test.method.Type", // interface to call on
- "Method"); // method name
- if (NULL == msg) {
- fprintf(stderr, "Message Null/n");
- exit(1);
- }
- // append arguments
- dbus_message_iter_init_append(msg, &args);
- if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, ¶m)) {
- fprintf(stderr, "Out Of Memory!/n");
- exit(1);
- }
- // send message and get a handle for a reply
- if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
- fprintf(stderr, "Out Of Memory!/n");
- exit(1);
- }
- if (NULL == pending) {
- fprintf(stderr, "Pending Call Null/n");
- exit(1);
- }
- dbus_connection_flush(conn);
- printf("Request Sent/n");
- // free message
- dbus_message_unref(msg);
- // block until we recieve a reply
- dbus_pending_call_block(pending);
- // get the reply message
- msg = dbus_pending_call_steal_reply(pending);
- if (NULL == msg) {
- fprintf(stderr, "Reply Null/n");
- exit(1);
- }
- // free the pending message handle
- dbus_pending_call_unref(pending);
- // read the parameters
- if (!dbus_message_iter_init(msg, &args))
- fprintf(stderr, "Message has no arguments!/n");
- else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args))
- fprintf(stderr, "Argument is not boolean!/n");
- else
- dbus_message_iter_get_basic(&args, &stat);
- if (!dbus_message_iter_next(&args))
- fprintf(stderr, "Message has too few arguments!/n");
- else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args))
- fprintf(stderr, "Argument is not int!/n");
- else
- dbus_message_iter_get_basic(&args, &level);
- printf("Got Reply: %d, %d/n", stat, level);
- // free reply
- dbus_message_unref(msg);
- }
- void reply_to_method_call(DBusMessage* msg, DBusConnection* conn)
- {
- DBusMessage* reply;
- DBusMessageIter args;
- bool stat = true;
- dbus_uint32_t level = 21614;
- dbus_uint32_t serial = 0;
- char* param = "";
- // read the arguments
- if (!dbus_message_iter_init(msg, &args))
- fprintf(stderr, "Message has no arguments!/n");
- else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
- fprintf(stderr, "Argument is not string!/n");
- else
- dbus_message_iter_get_basic(&args, ¶m);
- printf("Method called with %s/n", param);
- // create a reply from the message
- reply = dbus_message_new_method_return(msg);
- // add the arguments to the reply
- dbus_message_iter_init_append(reply, &args);
- if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &stat)) {
- fprintf(stderr, "Out Of Memory!/n");
- exit(1);
- }
- if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &level)) {
- fprintf(stderr, "Out Of Memory!/n");
- exit(1);
- }
- // send the reply && flush the connection
- if (!dbus_connection_send(conn, reply, &serial)) {
- fprintf(stderr, "Out Of Memory!/n");
- exit(1);
- }
- dbus_connection_flush(conn);
- // free the reply
- dbus_message_unref(reply);
- }
- /**
- * Server that exposes a method call and waits for it to be called
- */
- void listen()
- {
- DBusMessage* msg;
- DBusMessage* reply;
- DBusMessageIter args;
- DBusConnection* conn;
- DBusError err;
- int ret;
- char* param;
- printf("Listening for method calls/n");
- // initialise the error
- dbus_error_init(&err);
- // connect to the bus and check for errors
- conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Connection Error (%s)/n", err.message);
- dbus_error_free(&err);
- }
- if (NULL == conn) {
- fprintf(stderr, "Connection Null/n");
- exit(1);
- }
- // request our name on the bus and check for errors
- ret = dbus_bus_request_name(conn, "test.method.server", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Name Error (%s)/n", err.message);
- dbus_error_free(&err);
- }
- if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
- fprintf(stderr, "Not Primary Owner (%d)/n", ret);
- exit(1);
- }
- // loop, testing for new messages
- while (true) {
- // non blocking read of the next available message
- dbus_connection_read_write(conn, 0);
- msg = dbus_connection_pop_message(conn);
- // loop again if we haven't got a message
- if (NULL == msg) {
- sleep(1);
- continue;
- }
- // check this is a method call for the right interface & method
- if (dbus_message_is_method_call(msg, "test.method.Type", "Method"))
- reply_to_method_call(msg, conn);
- // free the message
- dbus_message_unref(msg);
- }
- }
- /**
- * Listens for signals on the bus
- */
- void receive()
- {
- DBusMessage* msg;
- DBusMessageIter args;
- DBusConnection* conn;
- DBusError err;
- int ret;
- char* sigvalue;
- printf("Listening for signals/n");
- // initialise the errors
- dbus_error_init(&err);
- // connect to the bus and check for errors
- conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Connection Error (%s)/n", err.message);
- dbus_error_free(&err);
- }
- if (NULL == conn) {
- exit(1);
- }
- // request our name on the bus and check for errors
- ret = dbus_bus_request_name(conn, "test.signal.sink", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Name Error (%s)/n", err.message);
- dbus_error_free(&err);
- }
- if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
- exit(1);
- }
- // add a rule for which messages we want to see
- dbus_bus_add_match(conn, "type='signal',interface='test.signal.Type'", &err); // see signals from the given interface
- dbus_connection_flush(conn);
- if (dbus_error_is_set(&err)) {
- fprintf(stderr, "Match Error (%s)/n", err.message);
- exit(1);
- }
- printf("Match rule sent/n");
- // loop listening for signals being emmitted
- while (true) {
- // non blocking read of the next available message
- dbus_connection_read_write(conn, 0);
- msg = dbus_connection_pop_message(conn);
- // loop again if we haven't read a message
- if (NULL == msg) {
- sleep(1);
- continue;
- }
- // check if the message is a signal from the correct interface and with the correct name
- if (dbus_message_is_signal(msg, "test.signal.Type", "Test")) {
- // read the parameters
- if (!dbus_message_iter_init(msg, &args))
- fprintf(stderr, "Message Has No Parameters/n");
- else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
- fprintf(stderr, "Argument is not string!/n");
- else
- dbus_message_iter_get_basic(&args, &sigvalue);
- printf("Got Signal with value %s/n", sigvalue);
- }
- // free the message
- dbus_message_unref(msg);
- }
- }
- int main(int argc, char** argv)
- {
- if (2 > argc) {
- printf ("Syntax: dbus-example [send|receive|listen|query] [<param>]/n");
- return 1;
- }
- char* param = "no param";
- if (3 >= argc && NULL != argv[2]) param = argv[2];
- if (0 == strcmp(argv[1], "send"))
- sendsignal(param);
- else if (0 == strcmp(argv[1], "receive"))
- receive();
- else if (0 == strcmp(argv[1], "listen"))
- listen();
- else if (0 == strcmp(argv[1], "query"))
- query(param);
- else {
- printf ("Syntax: dbus-example [send|receive|listen|query] [<param>]/n");
- return 1;
- }
- return 0;
- }
makefile
- CC = arm-linux-gcc
- CFLAGS += -Wall -g -I/opt/gtkfb/include/dbus-1.0 -I/opt/gtkfb/lib/dbus-1.0/include
- LIBS += -Wall -g -L/opt/gtkfb/lib -ldbus-1 -lpthread -lrt
- TARGET = sample
- OBJ = $(TARGET).o
- all: $(TARGET)
- %o: %c
- $(CC) $(CFLAGS) -c $< -o $@
- $(TARGET): $(OBJ)
- $(CC) $(LIBS) -o $(TARGET) $(OBJ)
编译后得到 sample 可执行文件,放入开发板文件系统
执行,出现如下错误,查看资料得知,需要先配置dbus才可以使用它
作如下的配置:
1.先运行dbus-daemon
$ dbus-daemon –system –print-pid –print-address
出现如下错误:Failed to start message bus: Could not get UID and GID for username “messagebus”
添加一个用户就可
$ adduser messagebus
2.再执行sample 出现如下错误
D-Bus library appears to be incorrectly set up; failed to read machine uuid: Failed to open “/opt/gtkfb/lib/dbus/machine-id”: No such file or directory
缺少machine-id ,dbus 提供dbus-uuidgen命令产生machine-id
$ dbus-uuidgen > /opt/gtkfb/lib/dbus/machine-id
3.再执行sample 出现如下错误
Connection Error (/opt/gtkfb/bin/dbus-launch terminated abnormally with the foll
owing error: Autolaunch requested, but X11 support not compiled in.
这个需要先获得DBUS_SESSION_BUS_ADDRESS,使用 dbus-launch命令
$ dbus-launch
DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/dbus-7dbR7xlNbT,guid=3c7319d183feacf6a4faf8160000029b
DBUS_SESSION_BUS_PID=452
$ export DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/dbus-7dbR7xlNbT,guid=3c7319d183feacf6a4faf8160000029b
再执行sample就可以启动了
signal运行实例
运行server
$ ./sample receive &
Listening for signals
Match rule sent
运行client
$ ./sample send lt2440
Sending signal with value lt2440
Signal Sent
Got Signal with value lt2440
method运行实例
运行server
$ ./sample listen &
Listening for method calls
运行client
$ ./sample query lt2440
Calling remote method with luther.gliethttp.12345678
Request Sent
Method called with lt2440
Got Reply: 0, 21614
dbus在lt2440开发板上成功执行。dbus封装的程序通信比较方便,简单,高效
- dbus 初探 版本 dbus-1.4.0
- dbus
- DBUS
- dbus
- DBUS
- dbus
- DBUS
- DBUS
- dbus
- 初探dbus(1)
- dbus 之 dbus-glib
- DBUS移植
- DBUS问题
- DBUS 记录
- dbus 例程
- DBus 介绍
- DBus例子
- DBus截例
- 嵌入式Linux之我行——s3c2440的IO静态映射的分析
- 设置Gvim的启动位置与窗口大小,代码折叠及配色等
- 百度笔试题5.1
- RMAN备份(九)
- Android Camera Framework Stream(一)
- dbus 初探 版本 dbus-1.4.0
- 嵌入式Linux之我行——设备文件系统剖析与使用
- request_irq() | 注册中断服务
- Python-csrf
- Linux 各文件夹的作用
- 各种排序算法分析总结
- Android Camera Framework Stream(二)
- zoj 1101 Gamblers 为什么总是WA?
- [转]关于C与C++中互相调用动态链接库的问题