FPC and DBus

From Free Pascal wiki
Revision as of 22:20, 7 November 2019 by Mgpoole (talk | contribs) (→‎Sending a Signal: added example code)
Jump to navigationJump to search

English (en) español (es)

Overview

DBUS is a GNU library that implements inter-process communication. It's the default library of this kind for GNU applications. It can often be found on Linux machines.

This library provides a simple way for applications to talk to one another, using a bus sytem. These headers are the translation of the low-level C API for DBUS. In the future it is desirable that these headers be wrapped around a class to make their use easier.

Documentation

Independently from what you want to achieve, a lot of the code for a program that uses DBUS will be very similar. This is the startup and finalization code.

Startup

On startup you need to connect to the bus. Usually there is a system and a session bus. Depending on the configuration of the system, you may not have access to the system bus. Next you need to request a name on the bus. Below is some simple startup code.

var
  err: DBusError;
  conn: PDBusConnection;
  ret: cint;
begin
  { Initializes the error handling }
  dbus_error_init(@err);
  
  { Connection }
  conn := dbus_bus_get(DBUS_BUS_SESSION, @err);

  if dbus_error_is_set(@err) <> 0 then
  begin
    WriteLn('Connection Error: ' + err.message);
    dbus_error_free(@err);
  end;
  
  if conn = nil then Exit;
  
  { Request the name of the bus }
  ret := dbus_bus_request_name(conn, 'test.method.server', DBUS_NAME_FLAG_REPLACE_EXISTING, @err);

  if dbus_error_is_set(@err) <> 0 then
  begin
    WriteLn('Name Error: ' + err.message);
    dbus_error_free(@err);
  end;
  
  if ret <> DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER then Exit;

  ....

Shutdown

When you no longer need the bus, you should close the connection. A good place to do this in most cases is right before the application terminates. The method used to do this depends on whether the connection is shared or private. Private connections are created using dbus_connection_open_private or dbus_bus_get_private and are closed using dbus_connection_close;

  { Finalization }
  dbus_connection_close(conn);

Shared connections, created using dbus_connection_open or dbus_bus_get are owned by libdbus and applications should only unref them, never close them. Most connections are shared connections.

  { Finalization }
  dbus_connection_unref(conn);

Sending a Signal

Signals are broadcasts from a DBus object to any client applications that require the information that it carries. A signal message contains the name of the interface that specifies the signal; the name of the signal; the bus name of the process sending the signal; and any arguments.

The originating application first creates a signal message with dbus_message_new_signal(), then appends any arguments before sending with dbus_connection_send().

procedure SendSignalExample;
var
  DBusSerial: Cardinal;
  err: DBusError;
  conn: PDBusConnection;
  ret: cint;
  msg: PDBusMessage;
  args: DBusMessageIter;
  SignalData: PChar;
begin
  DBusSerial := 0;
  SignalData := 'This string is sent with the signal';

   // 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 (0<>dbus_error_is_set(@err)) then
      begin
      writeln( 'Connection Error :', err.message);
      dbus_error_free(@err);
      end;
   if conn = nil then exit;

   // request a name on the bus and check for errors
   ret := dbus_bus_request_name(conn, 'test.signal.source', DBUS_NAME_FLAG_REPLACE_EXISTING , @err);
   if (0<>dbus_error_is_set(@err)) then
      begin
      writeln('Error: ', err.message);
      dbus_error_free(@err);
      end;
   if ret<>DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER then exit;

   // create a signal and check for errors
   msg := dbus_message_new_signal('/test/signal/Object', // object name
                                 'test.signal.Type',     // interface name
                                 'TestSignal');          // signal name
   if msg = nil then
      begin
        writeln('msg is nil');
        exit;
      end;
   // initialise argument payload
   dbus_message_iter_init_append(msg, @args);

   // append arguments onto signal
   if (0=dbus_message_iter_append_basic(@args, DBUS_TYPE_STRING, @SignalData)) then
      begin
        writeln('Out of memory(1)');
       exit;
      end;

   // send the message and flush the connection
   if (0=dbus_connection_send(conn, msg, @DBusSerial)) then
      begin
        writeln('Out of memory(2)');
        exit;
      end;
   dbus_connection_flush(conn);

   // free the message and finish using the connection
   dbus_message_unref(msg);
   dbus_connection_unref(conn);
end;

Receiving a Signal

Calling a Method

Responding to Method calls

Authors

Felipe Monteiro de Carvalho


License

Status

Status: Beta

Download

Installed by default

The FPC package for DBUS resides in packages/dbus in the FPC (2.2.2+) packages tree.

You can download a full FPC repository and it will be included.

Older versions

For older versions: you can download the subversion version of this project using this command:

svn checkout http://svn.freepascal.org/svn/fpc/trunk/packages/dbus dbus

Bug Reporting

Tests are necessary to verify if all functions and structures are declared properly. Tests were done on Windows, FreeBSD and Linux operating systems. It is necessary to test if the modules work correctly in other operating system.

You can post Bug Reports to the regular bug tracker (make sure to choose the FPC project and select the Packages category)

Change Log

  • ??.??.06 DBus headers version 0.1
  1. Under construction
  • 03.11.2010 Updated DBus headers to version 1.2.16

Help

Please send help requests to the Free Pascal mailling list or on apache-modules mailing list.

See also

  • [1] - A Tutorial about using the DBUS C API
  • [2] - An introduction to using DBUS with FPC, with source code