How to compile a basic D-Bus/glib example?

29,931

Solution 1

Tutorials like this one generally assume that you have some knowledge of the language it is written for, in this case C, as well as the operating system you will run it on.

Looking at the tutorial, I see that it only contains a main function. As such, you will need to add the proper #include directives in order for this to work:

#include <stdlib.h>          // for exit()   
#include <dbus/dbus.h>       // for dbus_*   
#include <dbus/dbus-glib.h>  // for dbus_g_*

Also, you will need to compile the libraries (in this case dbus and dbus-glib), or use the pre-compiled ones from your operating system, in order to link them to the executable.

You will also need the header files provided with the source, or the "development" packages from your operating system.

Per example, on my Ubuntu workstation, I can install both the source and the header files like so:

sudo apt-get -y install dbus libdbus-1-dev libdbus-glib-1-2 libdbus-glib-1-dev

Once they are compiled (or properly installed), you proceed to compile the program. You will need to specify the proper include paths and libraries to link to the compiler/linker. Per example, with GCC and my current setup it would be:

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

This should create an executable a.out in the current directory.

Granted, I have a few years of experience with C and Linux so I get figure out all that stuff easily. If you're looking to start with C, you probably should start with something easier though.

Solution 2

Note that libdbus-glib is deprecated, unmaintained and should not be used for accessing D-Bus from C: use GDBus instead. libdbus-1 is not recommended either: it is maintained, but is a much lower-level API for using D-Bus, and does not have all the convenience features of GDBus.

As enthusiasticgeek says, there’s good GDBus documentation available.

(libdbus-glib and libdbus-1 deliberately not linked to avoid giving them google juice.)

Solution 3

Based on 'netcoder's' answer is the program that worked for me.

#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;
}

and 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 

Note: This webpage has a good D-bus example https://developer.gnome.org/gio//2.36/GDBusProxy.html

Solution 4

Looks like you have to include <dbus/dbus-glib.h> separately, as it is not automatically included by <dbus.h>

Solution 5

Based on the error returned by your gcc command. The gcc is able to see the <dbus/dbus.h> file (otherwise it will display error message indicating that he is not able to see the header file) but is not able to see some variables that should be exist in this file (‘DBusGConnection’ and ‘GError’) . May be you are not using the adequate version of dbus

and try to use make file instead of one command

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 $@ $^

dbus-example.bin: my_dbus.o
    $(CC) $(LDFLAGS) -o $@ $^

clean:
    rm -f *.o dbus-example.bin
Share:
29,931

Related videos on Youtube

tvuillemin
Author by

tvuillemin

Hi! I'm a software developer with a strong DevOps culture. I make production-ready applications in Python (experienced) or Go (enthusiastic noob). I'm used to deal with large amounts of data and version transitions. I build continuous delivery systems for my apps including build, tests, and deployment. I make sure that everything is monitored. I realize that communication is the key of solving problems, both within the team and with the customers. In my spare time, I like gaming, sailing, cycling and cooking. And squirrels. Squirrels are awesome. Cheers!

Updated on July 09, 2022

Comments

  • tvuillemin
    tvuillemin almost 2 years

    I'm trying to learn how to use D-Bus with C bindings. I've never used D-Bus before. I'm following this tutorial, which I assume is the official one (Freedesktop.org). I've read it until this paragraph that gives a first sample program , but unfortunately I don't see any indication on this page about how to compile it or which libraries to include. Did I miss something ?

    My OS is Ubuntu 10.04 32bit. I installed the libdbus-glib-1-dev package. I tried to add #include <dbus/dbus.h> at the beginning of the source file, and to compile with

    $ 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
    

    but I just keep failing:

    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’
    ...
    

    Did I miss a point in the tutorial ? It not, could you please help me compile this piece of code ?

    Thanks in advance.

  • tvuillemin
    tvuillemin over 11 years
    Sorry, just a copy-past error while writing this question, my bad.
  • tvuillemin
    tvuillemin over 11 years
    Thanks for your help. It makes me realize that I actually asked the wrong question. I should have told clearly that it wasn't about C. Anyway, your answer is so complete that I got my answer and I'm sure it will help someone else, so thanks :)
  • Paul Gorbas
    Paul Gorbas over 9 years
    Any advice on how to do this in Eclipse?? The -I directives go into the project properties c/c++ General | Path and Symbols | Includes, but I can not see a way to include the -l directives ?? My dbus install did not come with any libraries to include ???