Как составить базовый пример D-Bus/glib?
Я пытаюсь узнать, как использовать D-Bus с привязками C. Раньше я никогда не использовал D-Bus. Я следую за этим tutorial, который, как я полагаю, является официальным (Freedesktop.org). Я читал его до этого абзаца, который дает первую примерную программу
, но, к сожалению, я не вижу никаких указаний на этой странице о том, как их компилировать или какие библиотеки включать. Я что-то пропустил?
Моя ОС - Ubuntu 10.04 32bit. Я установил пакет libdbus-glib-1-dev
. Я попытался добавить #include <dbus/dbus.h>
в начало исходного файла и скомпилировать с помощью
$ gcc -ldbus-1 -I/usr/include/dbus-1.0/ -I/usr/lib/i386-linux-gnu/dbus-1.0/include -o my_dbus.bin my_dbus.c
но я просто продолжаю терпеть неудачу:
my_dbus.c: In function ‘main’:
my_dbus.c:7:3: error: unknown type name ‘DBusGConnection’
my_dbus.c:8:3: error: unknown type name ‘GError’
...
Я пропустил точку в учебнике? Это не так, не могли бы вы помочь мне скомпилировать этот фрагмент кода?
Спасибо заранее.
Ответы
Ответ 1
Подобные учебники обычно предполагают, что у вас есть знания языка, на котором он написан, в данном случае C, а также операционной системы, на которой вы будете его использовать.
Глядя на учебник, я вижу, что он содержит только main
функцию. Таким образом, вам нужно будет добавить соответствующие директивы #include
чтобы это работало:
#include <stdlib.h> // for exit()
#include <dbus/dbus.h> // for dbus_*
#include <dbus/dbus-glib.h> // for dbus_g_*
Также вам необходимо скомпилировать библиотеки (в данном случае dbus
и dbus-glib
) или использовать предварительно скомпилированные библиотеки из вашей операционной системы, чтобы связать их с исполняемым файлом.
Вам также понадобятся заголовочные файлы, поставляемые с исходным кодом, или пакеты "разработки" из вашей операционной системы.
Например, на моей рабочей станции Ubuntu я могу установить как исходные файлы, так и файлы заголовков следующим образом:
sudo apt-get -y install dbus libdbus-1-dev libdbus-glib-1-2 libdbus-glib-1-dev
Как только они скомпилированы (или правильно установлены), вы приступаете к компиляции программы. Вам нужно будет указать правильные пути включения и библиотеки для связи с компилятором/компоновщиком. Например, с GCC и моей текущей настройкой это будет:
gcc test.c -I/usr/include/dbus-1.0 \
-I/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
-I/usr/include/glib-2.0 \
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ \
-ldbus-1 \
-ldbus-glib-1 \
-Wall -Wextra
Это должно создать исполняемый файл a.out
в текущем каталоге.
Конечно, у меня есть несколько лет опыта работы с C и Linux, поэтому я легко разбираюсь в этом. Если вы хотите начать с C, вам, вероятно, следует начать с чего-то более простого.
Ответ 2
На основе 'netcoder' ответ - это программа, которая работала для меня.
#include <stdlib.h> // for exit()
#include <dbus/dbus.h> // for dbus_*
#include <dbus/dbus-glib.h> // for dbus_g_*
int
main (int argc, char **argv)
{
DBusGConnection *connection;
GError *error;
DBusGProxy *proxy;
char **name_list;
char **name_list_ptr;
g_type_init ();
error = NULL;
connection = dbus_g_bus_get (DBUS_BUS_SESSION,
&error);
if (connection == NULL)
{
g_printerr ("Failed to open connection to bus: %s\n",
error->message);
g_error_free (error);
exit (1);
}
/* Create a proxy object for the "bus driver" (name "org.freedesktop.DBus") */
proxy = dbus_g_proxy_new_for_name (connection,
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);
/* Call ListNames method, wait for reply */
error = NULL;
if (!dbus_g_proxy_call (proxy, "ListNames", &error, G_TYPE_INVALID,
G_TYPE_STRV, &name_list, G_TYPE_INVALID))
{
/* Just do demonstrate remote exceptions versus regular GError */
if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
g_printerr ("Caught remote method exception %s: %s",
dbus_g_error_get_name (error),
error->message);
else
g_printerr ("Error: %s\n", error->message);
g_error_free (error);
exit (1);
}
/* Print the results */
g_print ("Names on the message bus:\n");
for (name_list_ptr = name_list; *name_list_ptr; name_list_ptr++)
{
g_print (" %s\n", *name_list_ptr);
}
g_strfreev (name_list);
g_object_unref (proxy);
return 0;
}
и Makefile
file=1
sample:
g++ -g $(file).cc -o $(file) -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ -ldbus-1 -ldbus-glib-1 -Wall -Wextra -lglib-2.0 -lgio-2.0 -lgobject-2.0 -lgthread-2.0
Примечание. На этой веб-странице есть хороший пример D-bus https://developer.gnome.org/gio//2.36/GDBusProxy.html
Ответ 3
Похоже, вы должны включать <dbus/dbus-glib.h>
отдельно, так как он не включается автоматически <dbus.h>
Ответ 4
Обратите внимание, что libdbus-glib устарел, не поддерживается и не должен использоваться для доступа к D-Bus из C: вместо этого используйте GDBus. libdbus-1 не рекомендуется: он поддерживается, но является гораздо более низким уровнем API для использования D-Bus и не имеет всех удобных функций GDBus.
Как говорит энтузиазм, theres good Доступна документация GDBus.
(libdbus-glib и libdbus-1 намеренно не связаны, чтобы не давать им сок google.)
Ответ 5
На основании ошибки, возвращаемой вашей командой gcc. Gcc может видеть файл <dbus/dbus.h>
(в противном случае будет отображаться сообщение об ошибке, указывающее, что он не может видеть файл заголовка), но не может видеть некоторые переменные, которые должны существовать в этом файле (‘DBusGConnection’
и ‘GError’
). Возможно, вы не используете подходящую версию dbus
и попробуйте использовать файл make вместо одной команды
LDFLAGS+=-ldbus
CFLAGS+=-I/usr/include/dbus-1.0/
CFLAGS+=-I/usr/lib/i386-linux-gnu/dbus-1.0/include
all: dbus-example.bin
%.o: %.c
$(CC) $(CFLAGS) -c -o [email protected] $^
dbus-example.bin: my_dbus.o
$(CC) $(LDFLAGS) -o [email protected] $^
clean:
rm -f *.o dbus-example.bin