C++ Language Binding

From Apache OpenOffice Wiki
Jump to: navigation, search



This chapter describes the UNO C++ language binding. It provides an experienced C++ programmer the first steps in UNO to establish UNO interprocess connections to a remote Apache OpenOffice and to use its UNO objects.

Library Overview

The illustration below gives an overview about the core libraries of the UNO component model.

Shared Libraries for C++ UNO

These shared libraries can be found in the <officedir>/program folder of your Apache OpenOffice installation. The label (C) in the illustration above means C linkage and (C++) means C++ linkage. For all libraries, a C++ compiler to build is required.

The basis for all UNO libraries is the sal library. It contains the system abstraction layer (sal) and additional runtime library functionality, but does not contain any UNO-specific information. The commonly used C-functions of the sal library can be accessed through C++ inline wrapper classes. This allows functions to be called from any other programming language, because most programming languages have some mechanism to call a C function.

The salhelper library is a small C++ library which offers additional runtime library functionality, that could not be implemented inline.

The cppu (C++UNO) library is the core UNO library. It offers methods to access the UNO type library, and allows the creation, copying and comparing values of UNO data types in a generic manner. Moreover, all UNO bridges (= mappings + environments) are administered in this library.

The examples msci_uno.dll, libsunpro5_uno.so and libgcc2_uno.so are only examples for language binding libraries for certain C++ compilers.

The cppuhelper library is a C++ library that contains important base classes for UNO objects and functions to bootstrap the UNO core. C++ Components and UNO programs have to link the cppuhelper library.

All the libraries shown above will be kept compatible in all future releases of UNO. You will be able to build and link your application and component once, and run it with the current and later versions of Apache OpenOffice.

System Abstraction Layer

C++ UNO client programs and C++ UNO components use the system abstraction layer (sal) for types, files, threads, interprocess communication, and string handling. The sal library offers operating system dependent functionality as C functions. The aim is to minimize or to eliminate operating system dependent #ifdef in libraries above sal. Sal offers high performance access because sal is a thin layer above the API offered by each operating system.

Documentation note.png In Apache OpenOffice GUI APIs are encapsulated in the vcl library.

Sal exports only C symbols. The inline C++ wrapper exists for convenience. Refer to the UNO C++ reference that is part of the Apache OpenOffice SDK or in the References section of udk.openoffice.org to gain a full overview of the features provided by the sal library. In the following sections, the C++ wrapper classes will be discussed. The sal types used for UNO types are discussed in section Type Mappings. If you want to use them, look up the names of the appropriate include files in the C++ reference.

File Access

The classes listed below manage platform independent file access. They are C++ classes that call corresponding C functions internally.

  • osl::FileBase
  • osl::VolumeInfo
  • osl::FileStatus
  • osl::File
  • osl::DirectoryItem
  • osl::Directory

An unfamiliar concept is the use of absolute filenames throughout the whole API. In a multithreaded program, the current working directory cannot be relied on, thus relative paths must be explicitly made absolute by the caller.

Threadsafe Reference Counting

The functions osl_incrementInterlockedCount() and osl_decrementInterlockedCount() in the global C++ namespace increase and decrease a 4-byte counter in a threadsafe manner. This is needed for reference counted objects. Many UNO APIs control object lifetime through refcounting. Since concurrent incrementing the same counter does not increase the reference count reliably, these functions should be used. This is faster than using a mutex on most platforms.

Threads and Thread Synchronization

The class osl::Thread is meant to be used as a base class for your own threads. Overwrite the run() method.

The following classes are commonly used synchronization primitives:

  • osl::Mutex
  • osl::Condition
  • osl::Semaphore

Socket and Pipe

The following classes allow you to use interprocess communication in a platform independent manner:

  • osl::Socket
  • osl::Pipe

Strings

The classes rtl::OString (8-bit, encoded) and rtl::OUString (16-bit, UTF-16) are the base-string classes for UNO programs. The strings store their data in a heap memory block. The string is refcounted and incapable of changing, thus it makes copying faster and creation is an expensive operation. An OUString can be created using the static function OUString::createFromASCII() or it can be constructed from an 8-bit string with encoding using this constructor:

  OUString( const sal_Char * value, 
           sal_Int32 length, 
           rtl_TextEncoding encoding, 
           sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS );

It can be converted into an 8-bit string, for example, for printf() using the rtl::OUStringTo­OString() function that takes an encoding, such as RTL_TEXTENCODING_ASCII_US.

For fast string concatenation, the classes rtl::OStringBuffer and rtl::OUStringBuffer should be used, because they offer methods to concatenate strings and numbers. After preparing a new string buffer, use the makeStringAndClear() method to create the new OUString or OString. The following example illustrates this:

  sal_Int32 n = 42;
  double pi = 3.14159;
 
  // create a buffer with a suitable size, rough guess is sufficient
  // stringbuffer extends if necessary
  OUStringBuffer buf( 128 );
 
  // append an ascii string
  buf.appendAscii( "pi ( here " );
 
  // numbers can be simply appended 
  buf.append( pi );
  // RTL_CONSTASCII_STRINGPARAM()
  // lets the compiler count the stringlength, so this is more efficient than
  // the above appendAscii call, where the length of the string must be calculated at
  // runtime
  buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" ) multiplied with " ) );
  buf.append( n );
  buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" gives ") );
  buf.append( (double)( n * pi ) );
  buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "." ) );
 
  // now transfer the buffer into the string.
  // afterwards buffer is empty and may be reused again !
  OUString string = buf.makeStringAndClear();
 
  // You could of course use the OStringBuffer directly to get an OString
  OString oString = rtl::OUStringToOString( string , RTL_TEXTENCODING_ASCII_US );
 
  // just to print something 
  printf( "%s\n" ,oString.getStr() );
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages