Skip to main content

The Caché C++ Binding

The Caché C++ binding provides a simple, direct way to use Caché objects within a C++ application. You can create C++ applications that work with the Caché database in the following ways:

  • The Caché C++ binding

    The Caché C++ binding lets C++ applications work with objects on a Caché server. The Caché Class Generator can create a C++ proxy class for any Caché class. Proxy classes contain standard C++ code that can be compiled and used within your C++ application, providing access to the properties and methods of the corresponding Caché class.

    The C++ binding offers complete support for object database persistence, including concurrency and transaction control. In addition, there is a sophisticated data caching scheme to minimize network traffic when the Caché server and C++ applications are located on separate machines.

  • Dynamic binding

    Instead of using compiled C++ proxy classes, you can work with Caché classes dynamically, at runtime. This can be useful for writing applications or tools that deal with classes in general and do not depend on particular Caché classes.

  • Light C++ Binding

    The Light C++ Binding (LCB) is a limited subset of the Caché C++ library intended primarily for loading simple data at very high speed. It combines your C++ application and the Caché Object Server into a single process, using intraprocess communications rather than TCP/IP to exchange data between them. For basic object manipulation (creating objects, opening objects by Id, updating, and deleting), it is ten to twenty times faster than the standard C++ binding.

  • The Caché ODBC driver

    Caché includes a standard ODBC driver that offers high-performance relational access to Caché, including the ability to execute SQL queries against the database. The C++ binding provides special classes to encapsulate the complexity of ODBC. For maximum flexibility, applications can use ODBC and the Caché C++ Binding at the same time.

Each of these features is discussed in the following chapters.

This document assumes a prior understanding of C++ and the C++ standard library. Several C++ compilers are supported, but Caché does not include a C++ compiler or development environment.

C++ Binding Architecture

The Caché C++ Binding gives C++ applications a way to access and manipulate objects contained within a Caché server. These objects can be persistent objects stored within the Caché object database, or they can be transient objects that perform operations within a Caché server.

The Caché C++ Binding consists of the following components:

  • The Caché C++ Generator

    The C++ Generator is a program that generates C++ proxy classes (source and header files) from classes defined in the Caché Class Dictionary.

  • The Caché C++ library

    The C++ library is a set of C++ classes used by the Caché C++ Generator to implement all the functionality of the C++ proxy classes. The library also includes a set of proxy classes for Caché server classes that require specialized adaptations to fit into the framework of the C++ standard library.

  • The Caché Object Server

    The Caché Object Server is a high performance server process that manages communication between C++ clients and a Caché database server. It communicates using standard networking protocols (TCP/IP), and can run on any platform supported by Caché. The Caché Object Server is used by all Caché language bindings, including C++, Java, JDBC, ODBC, Perl, and Python.

The Caché C++ Generator can create C++ client classes for any classes contained within the Caché Class Dictionary. These generated C++ classes communicate at runtime (using TCP/IP sockets) with their corresponding Caché class on a Caché server. This is illustrated in the following diagram:

C++ Client/Server Class Architecture
generated description: cppflow

The basic mechanism works as follows:

  • You define one or more classes within Caché. These can be persistent objects stored within the Caché database or transient objects that run within a Caché server.

  • The Caché C++ Class Generator creates C++ classes that correspond to your Caché classes. These classes include “stub” methods that invoke the corresponding Caché method on the server as well as accessor (get and set) methods for object properties.

  • At runtime, your C++ application connects to a Caché server. It can then create C++ objects that correspond to Caché objects maintained by the Caché Object Server. You can use these objects as you would any other C++ objects.

  • The system automatically manages all communications as well as client-side data caching. The actual deployment configuration is up to the application developer. The C++ client application and Caché server may reside on the same physical machine or they may be located on different machines. All communications between the C++ application and the Caché server use the standard TCP/IP protocol.

The runtime architecture consists of the following:

  • A Caché database server (or servers). The Caché server is responsible for database operations as well as the execution of Caché object methods.

  • A C++ "client" application into which your generated and compiled C++ proxy classes have been linked. (Although C++ is typically used for developing specialized tools and middle-ware, this document refers to such code as a client to differentiate it from the server code).

  • A connection between the application and the server provided by the connection classes included with the Caché C++ library.

Note:

The architecture of the Light C++ binding is quite different. It trades flexibility for speed by running all client and server operations on the same machine, using intraprocess communications instead of TCP/IP to exchange data between the C++ application and the Caché Object Server.

The Caché C++ Library

The Caché C++ binding's dynamic library of C++ classes implements the basic connection and caching mechanisms required to communicate with a Caché server.

The C++ components required to connect to Caché are contained within the C++ library file, which is located in the <cachesys>\dev\cpp\lib directory (see Default Caché Installation Directory in the Caché Installation Guide for the location of <cachesys> on your system). This directory contains different versions of the library that correspond to different build configurations for different platforms. A corresponding set of include files is located in the <cachesys>\dev\cpp\include subdirectory.

This library includes C++ versions of a number of the classes within the Caché class library, including %PersistentOpens in a new tab, %RegisteredObjectOpens in a new tab, %SerialObjectOpens in a new tab, the various Caché collection classes, and C++ versions of the various data type classes. In addition, the library contains the various classes used within a C++ application to manage communication with the Caché server.

The classes that are available for use in your C++ binding applications are listed and discussed in the following chapters:

Installation and Configuration

The Caché C++ binding software is not part of the standard Caché installation, but is offered as a option in the custom installation. For a list of the platforms that support the C++ Binding, see “Supported Client Platforms” in the online InterSystems Supported PlatformsOpens in a new tab document for this release.

Caché C++ binding applications require a C++ compiler that supports the C++ standard library. When you compile, your path should include the following directories (see Default Caché Installation Directory in the Caché Installation Guide for the location of <cachesys> on your system):

    <cachesys>\bin
    <cachesys>\dev\cpp\lib

A compiled C++ binding application will be able to access existing Caché classes with no additional setup, and can run on client machines that do not have Caché installed.

If Caché is installed with level 3 ("locked down") security, %Service_Bindings must be enabled in order to run the Caché C++ Generator.

The Light C++ Binding has additional requirements (see Installing the Light C++ Binding).

Building the Caché C++ Binding from Source

In some special situations, it may be useful to build the Caché C++ Binding from source code. The source code is installed if you select the "C++ SDK" option during a custom install of Caché. Windows MSVC projects or UNIX® makefiles can be customized as desired to use different versions of compilers or standard libraries. On UNIX®, gmake is required. As shipped, the sources, projects, and makefiles are identical to those used to build the production version of the C++ binding, but they can be used, without modification, to rebuild with different gcc versions on Linux. This may be necessary, since C++ code built with different gcc versions is often not binary-compatible.

Configuring Microsoft Visual Studio 2008

The following instructions describe the procedure for configuring a Caché C++ binding project in Microsoft Visual Studio 2008 under Windows XP. Some details may be different in other environments.

Setting Windows Environment Variables

Before you configure a project, you must set some Windows environment variables. The procedure is as follows:

  • In the Windows Start menu, select Settings > Control Panel > System. The System Properties dialog box opens.

  • In the System Properties dialog box, select the Advanced tab and then click the Environment Variables button. The Environment Variables dialog box opens.

  • In the System Variables section of the Environment Variables dialog box, add the following variables (see Default Caché Installation Directory in the Caché Installation Guide for the location of <cachesys> on your system):

    variable name

    variable value

    CACHEBIN <cachesys>\bin
    CACHECPPLIB <cachesys>\dev\cpp\lib
  • Append the following to the PATH system variable:

    ;%CACHEBIN%;%CACHECPPLIB%
    
    
Configuring the Project

Open the Visual Studio 2008 Project References window:

  • Open the project to be configured in Visual C++. In the following instructions, it is assumed that you have opened the Samples project located in <cachesys>\Dev\cpp\samples\msvc90\.

  • On the main menu, select Project > samples Properties. The samples Property Pages dialog box opens.

generated description: installvs2005

  • Click on the topmost item in the tree displayed on the left side of the dialog box. If this is not done, some of the tabs on the right side may be hidden.

  • In the samples Project Pages dialog box, make the changes described in the following procedures.

Enable wchar_t and Run-Time Type Information (RTTI) support:

  • In the Configuration drop-down box on the top left, select All Configurations.

  • In the menu tree on the left, select Configuration Properties > C/C++ > Language.

  • Make sure that the Treat wchar_t as Built-in Type has a value of Yes.

  • Make sure that the Enable Run-Time Type Info has a value of Yes.

  • Click the Apply button.

Specify the location of the C++ Binding header files:

  • In the menu tree on the left, select Configuration Properties > C/C++ > General.

  • In the Additional Include Directories text field, add:

    "<cachesys>\dev\cpp\include\"
    

    where <cachesys> refers to your Caché installation directory. Use a semicolon to separate it from any previous entries.

  • Click the Apply button.

Specify the location of the C++ Binding library directory:

  • In the Configuration drop-down box on the top left, select All Configurations.

  • In the menu tree on the left, select Configuration Properties > Linker > General.

  • In the Additional Library Directories text field, add:

    "$(CACHECPPLIB)\"
    

    Use a semicolon to separate it from any previous entries.

  • Click the Apply button.

Specify the location of the C++ Binding release library:

  • In the Configuration drop-down box on the top left, select Release.

  • In the menu tree on the left, select Configuration Properties > Linker > Input.

  • In the Additional Dependencies text field, add:

    cppbind_msvc90.lib
    

    Use a space to separate it from any previous entries.

  • When using the Light C++ Binding, add the following files:

    lcbind_msvc90.lib
    lcbclient.lib
    
  • Click the Apply button.

Specify the location of the C++ Binding debug library:

  • In the Configuration drop-down box on the top left, select Debug.

  • In the menu tree on the left, select Configuration Properties > Linker > Input.

  • In the Additional Dependencies text field, add:

    cppbind_msvc90d.lib
    

    Use a space to separate it from any previous entries.

  • When using the Light C++ Binding, add the following file:

    lcbind_msvc90d.lib
    
  • Click the Apply button.

Specify the runtime library for Release code generation:

  • In the Configuration drop-down box on the top left, select Release.

  • In the menu tree on the left, select Configuration Properties > C/C++ > Code Generation.

  • From the Runtime Library drop-down box, select Multi-threaded DLL (/MD).

  • Click the Apply button.

Specify the runtime library for Debug code generation:

  • In the Configuration drop-down box on the top left, select Debug.

  • In the menu tree on the left, select Configuration Properties > C/C++ > Code Generation.

  • From the Runtime Library drop-down box, select Multi-threaded Debug DLL (/MDd).

  • Click the OK button to close the samples Property Pages dialog.

Using the C++ Binding with ACE Libraries

When using C++ binding (regular or light) with ACE libraries on Windows, Caché header files must appear after ACE header files. This is because ACE headers include Microsoft winsock2.h, and the Caché C++ binding class headers include Microsoft windows.h. When both files are included, winsock2.h must appear before windows.h, or the MSVC compiler will fail due to definition conflicts.

Here is an example that includes ACE headers. Since Sample_Person.h and Sample_Address.h are Caché C++ Binding class headers, they must appear after all of the ACE headers:

#include "ace/OS_main.h"
#include "ace/streams.h"
#include "ace/Log_Msg.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/INET_Addr.h"
#include "ace/Service_Config.h"

#include "CPP-acceptor.h"

ACE_RCSID (non_blocking,
    test_sock_acceptor,
    "test_sock_acceptor.cpp,v 4.11 2004/10/27 21:06:58 shuston Exp")

typedef Svc_Handler<ACE_SOCK_STREAM> SVC_HANDLER;
typedef IPC_Server<SVC_HANDLER, ACE_SOCK_ACCEPTOR> IPC_SERVER;

#include "Sample_Person.h"  // C++ binding projected class header
#include "Sample_Address.h"  // C++ binding projected class header

Installing the Light C++ Binding

The Light C++ Binding (LCB) is a special purpose subset of the Caché C++ Binding, and has some extra requirements. For a list of the platforms that support the Light C++ Binding, see “Supported Client Platforms” in the online InterSystems Supported PlatformsOpens in a new tab document for this release.

Additional LCB Requirements

The design of LCB imposes the following extra requirements:

  • An environment variable named GLOBALS_HOME must be set to the full path of your Caché installation's <cache-root> directory (see “Default Caché Installation Directory” for the location of <cache-root> on your system). All connection attempts will fail if this environment variable is not set.

Note:
CACHEMGRDIR Deprecated

In previous releases, the required environment variable was CACHEMGRDIR, set to the <cache-root>/mgr directory rather than <cache-root>. Although this variable can still be used, it is deprecated. GLOBALS_HOME will be used instead of CACHEMGRDIR if both variables are set.

  • Unlike the regular C++ binding, the LCB architecture requires that Caché and the LCB application be installed on the same machine. This is necessary because they must share the same process (see Light C++ Binding Architecture).

  • Because LCB depends on the low-level Callin interface, the directory containing any LCB application must have a full path that uses fewer than 232 characters.

  • LCB uses a separate set of DLLs or shared libraries. For Windows, the files are: lcbind_msvc90.dll, lcbind_msvc90.lib, lcbclient.dll, lcbclient.lib, lcbind_msvc90d.dll, lcbind_msvc90d.lib

    For UNIX®, they are: liblcbind.so, liblcbclient.so

  • LINUX must be #defined when building LCB applications on Linux. The compile flags should include -DLINUX. See the Linux LCB sample application makefiles for examples.

  • LCB supports both level 1 ("minimal") and level 2 ("normal") security level installations. If Cache is installed with level 2 security, %Service_callin must be enabled to permit LCB to be connected.

Installation on the Windows 64 bit Platform

The Light C++ Binding is available for the Windows 64 bit platform. The Caché installation for 64 bit Windows still installs a 32 bit version of the standard Caché C++ Binding, since this is required for Studio. To build 64 bit versions of the LCB sample applications, use the "win64 Release" or "win64 Debug" configurations in the MSVC project files for these applications.

In order to run debug versions of LCB applications, you will need to download the Microsoft Platform SDK, which contains 64 bit debug versions of the libraries msvcrtd.dll and msvcp60d.dll. On 64 bit systems, installing Microsoft Visual Studio only provides the 32 bit versions of these files. (This is a general issue for C++ development on 64 bit systems, not specific to Caché or to the Light C++ Binding.)

Running Trusted Applications on UNIX®

Light C++ Binding applications on UNIX® must be run either by root, or by a user belonging to the cacheusr group, unless the application has been made a "trusted application". The recommended approach for deployed applications is to make them trusted applications. When this is done, the application runs with cacheusr as the effective group, but any user who has execute access to the application's executable file can run it (where execute access is controlled in the usual UNIX® manner using chmod).

To make a trusted application, do the following:

  • In the application makefile, among the flags for linking the application, specify -rpath <pathname> for the runtime pathnames of each of the libraries libcachet.so, liblcbind.so, and liblcbclient.so. For g++, use:

       -Xlinker -rpath -Xlinker <pathname>
    

    The runtime pathname is the pathname of the library in the environment in which the application will be run, which may be completely different from its pathname in the environment in which the application is built.

  • Alternatively, you could create soft links in /usr/lib for each of the libraries:

       cd /usr/lib
       ln -s <path>/libcachet.so libcachet.so
       ln -s <path>/liblcbind.so liblcbind.so
       ln -s <path>/liblcbclient.so liblcbclient.so
    
    

    If a trusted application uses shared libraries, the runtime locations of those shared libraries must be known at build time, so users can't use LD_LIBRARY_PATH to point to an untrusted version of the shared library. If no runtime path was specified for a given shared library at build time, the path /usr/lib/<libraryname> is assumed by default.

  • Set the owner, group, and suid bits of the LCB application. For example:

      chown <whoever> lcbdemo
      chgrp cacheusr lcbdemo
      chmod g+s lcbdemo
    

Sample Programs

The standard Caché installation includes several short sample programs, located in the C++ samples directory, <cachesys>\dev\cpp\samples\ (see Default Caché Installation Directory in the Caché Installation Guide for the location of <cachesys> on your system). The following sample programs are available:

  • samples.cpp — a simple program to demonstrate the standard Caché C++ binding.

  • lcbdemo.cpp — a demonstration of the Light C++ Binding.

  • mttest.cpp — a multi-threaded LCB test, to verify thread safety.

  • qtest.cpp — a query program using both the regular binding and multithreaded LCB.

MS Visual Studio project files for these programs are available in:..\samples\msvc90

For UNIX® platforms, run_samples.sh can be used in Caché 2008.1 and later.

Required Proxy Classes

The samples.cpp program uses classes from the Sample package in the SAMPLES namespace, which is also part of the standard Caché installation. The following C++ proxy class files must be generated (see Generating Proxy Classes) for Sample.PersonOpens in a new tab and Sample.AddressOpens in a new tab if they are not already present in the main C++ samples directory:

  • Sample_Person.h, Sample_Person.cpp

  • Sample_Address.h, Sample_Address.cpp

The lcbdemo.cpp program uses classes from the User package in the SAMPLES namespace. The following C++ proxy class files must be generated for User.PersonOpens in a new tab and User.testidkey2Opens in a new tab if they are not already present in the main C++ samples directory:

  • LC_User_Person.h, LC_User_Person.cpp

  • LC_User_testidkey2.h, LC_User_testidkey2.cpp

FeedbackOpens in a new tab