20

我正在尝试学习如何将 D-Bus 与 C 绑定一起使用。我以前从未使用过 D-Bus。我正在关注本教程,我认为它是官方的(Freedesktop.org)。在给出第一个示例程序的本段之前,我已经阅读了它,但不幸的是,我在此页面上没有看到任何关于如何编译它或包含哪些库的指示。我错过了什么 ?

我的操作系统是 Ubuntu 10.04 32 位。我安装了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’
...

我错过了教程中的一点吗?不是,你能帮我编译这段代码吗?

提前致谢。

4

5 回答 5

23

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.

于 2013-01-10T18:03:39.643 回答
5

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

于 2015-02-09T13:29:19.803 回答
4

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

于 2013-09-17T19:57:59.553 回答
2

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

于 2013-01-10T17:15:02.073 回答
1
于 2013-01-10T17:11:55.017 回答